hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
author jcoomes
Fri, 11 Jul 2008 16:11:34 -0700
changeset 972 b86fd2f84aaf
parent 971 f0b20be4165d
child 973 f00c7826d8c6
permissions -rw-r--r--
6718283: existing uses of *_FORMAT_W() were broken by 6521491 Reviewed-by: ysr, pbk
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
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
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
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/_psParallelCompact.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#include <math.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
// All sizes are in HeapWords.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
const size_t ParallelCompactData::Log2ChunkSize  = 9; // 512 words
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
const size_t ParallelCompactData::ChunkSize      = (size_t)1 << Log2ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
const size_t ParallelCompactData::ChunkSizeBytes = ChunkSize << LogHeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
const size_t ParallelCompactData::ChunkSizeOffsetMask = ChunkSize - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
const size_t ParallelCompactData::ChunkAddrOffsetMask = ChunkSizeBytes - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
const size_t ParallelCompactData::ChunkAddrMask  = ~ChunkAddrOffsetMask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// 32-bit:  128 words covers 4 bitmap words
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// 64-bit:  128 words covers 2 bitmap words
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
const size_t ParallelCompactData::Log2BlockSize   = 7; // 128 words
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
const size_t ParallelCompactData::BlockSize       = (size_t)1 << Log2BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
const size_t ParallelCompactData::BlockOffsetMask = BlockSize - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
const size_t ParallelCompactData::BlockMask       = ~BlockOffsetMask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
const size_t ParallelCompactData::BlocksPerChunk = ChunkSize / BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
ParallelCompactData::ChunkData::dc_shift = 27;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
ParallelCompactData::ChunkData::dc_mask = ~0U << dc_shift;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
ParallelCompactData::ChunkData::dc_one = 0x1U << dc_shift;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
ParallelCompactData::ChunkData::los_mask = ~dc_mask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
ParallelCompactData::ChunkData::dc_claimed = 0x8U << dc_shift;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
const ParallelCompactData::ChunkData::chunk_sz_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
ParallelCompactData::ChunkData::dc_completed = 0xcU << dc_shift;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
short   ParallelCompactData::BlockData::_cur_phase = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
bool      PSParallelCompact::_print_phases = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
ReferenceProcessor* PSParallelCompact::_ref_processor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
klassOop            PSParallelCompact::_updated_int_array_klass_obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
double PSParallelCompact::_dwl_mean;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
double PSParallelCompact::_dwl_std_dev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
double PSParallelCompact::_dwl_first_term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
double PSParallelCompact::_dwl_adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
bool   PSParallelCompact::_dwl_initialized = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
#ifdef VALIDATE_MARK_SWEEP
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
    84
GrowableArray<void*>*   PSParallelCompact::_root_refs_stack = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
GrowableArray<oop> *    PSParallelCompact::_live_oops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
GrowableArray<oop> *    PSParallelCompact::_live_oops_moved_to = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
GrowableArray<size_t>*  PSParallelCompact::_live_oops_size = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
size_t                  PSParallelCompact::_live_oops_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
size_t                  PSParallelCompact::_live_oops_index_at_perm = 0;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
    90
GrowableArray<void*>*   PSParallelCompact::_other_refs_stack = NULL;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
    91
GrowableArray<void*>*   PSParallelCompact::_adjusted_pointers = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
bool                    PSParallelCompact::_pointer_tracking = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
bool                    PSParallelCompact::_root_tracking = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
GrowableArray<size_t>   * PSParallelCompact::_cur_gc_live_oops_size = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops_moved_to = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
GrowableArray<size_t>   * PSParallelCompact::_last_gc_live_oops_size = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
// XXX beg - verification code; only works while we also mark in object headers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
static void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
verify_mark_bitmap(ParMarkBitMap& _mark_bitmap)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  PSPermGen* perm_gen = heap->perm_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  MutableSpace* perm_space = perm_gen->object_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  MutableSpace* old_space = old_gen->object_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  MutableSpace* eden_space = young_gen->eden_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  MutableSpace* from_space = young_gen->from_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  MutableSpace* to_space = young_gen->to_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  // 'from_space' here is the survivor space at the lower address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  if (to_space->bottom() < from_space->bottom()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    from_space = to_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    to_space = young_gen->from_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  HeapWord* boundaries[12];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  unsigned int bidx = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  const unsigned int bidx_max = sizeof(boundaries) / sizeof(boundaries[0]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  boundaries[0] = perm_space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  boundaries[1] = perm_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  boundaries[2] = old_space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  boundaries[3] = old_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  boundaries[4] = eden_space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  boundaries[5] = eden_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  boundaries[6] = from_space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  boundaries[7] = from_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  boundaries[8] = to_space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  boundaries[9] = to_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  boundaries[10] = to_space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  boundaries[11] = to_space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  BitMap::idx_t beg_bit = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  BitMap::idx_t end_bit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  BitMap::idx_t tmp_bit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  const BitMap::idx_t last_bit = _mark_bitmap.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    HeapWord* addr = _mark_bitmap.bit_to_addr(beg_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    if (_mark_bitmap.is_marked(beg_bit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      oop obj = (oop)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      assert(obj->is_gc_marked(), "obj header is not marked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      end_bit = _mark_bitmap.find_obj_end(beg_bit, last_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      const size_t size = _mark_bitmap.obj_size(beg_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      assert(size == (size_t)obj->size(), "end bit wrong?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      beg_bit = _mark_bitmap.find_obj_beg(beg_bit + 1, last_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      assert(beg_bit > end_bit, "bit set in middle of an obj");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      if (addr >= boundaries[bidx] && addr < boundaries[bidx + 1]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
        // a dead object in the current space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
        oop obj = (oop)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
        end_bit = _mark_bitmap.addr_to_bit(addr + obj->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
        assert(!obj->is_gc_marked(), "obj marked in header, not in bitmap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
        tmp_bit = beg_bit + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
        assert(beg_bit == end_bit, "beg bit set in unmarked obj");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
        assert(beg_bit == end_bit, "end bit set in unmarked obj");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
      } else if (addr < boundaries[bidx + 2]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
        // addr is between top in the current space and bottom in the next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
        end_bit = beg_bit + pointer_delta(boundaries[bidx + 2], addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
        tmp_bit = beg_bit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
        assert(beg_bit == end_bit, "beg bit set above top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
        assert(beg_bit == end_bit, "end bit set above top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
        bidx += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      } else if (bidx < bidx_max - 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
        bidx += 2; // ???
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
        tmp_bit = beg_bit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
        beg_bit = _mark_bitmap.find_obj_beg(tmp_bit, last_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
        assert(beg_bit == last_bit, "beg bit set outside heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
        beg_bit = _mark_bitmap.find_obj_end(tmp_bit, last_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
        assert(beg_bit == last_bit, "end bit set outside heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  } while (beg_bit < last_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
// XXX end - verification code; only works while we also mark in object headers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
const char* PSParallelCompact::space_names[] = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  "perm", "old ", "eden", "from", "to  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
void PSParallelCompact::print_chunk_ranges()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  tty->print_cr("space  bottom     top        end        new_top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  tty->print_cr("------ ---------- ---------- ---------- ----------");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  for (unsigned int id = 0; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    const MutableSpace* space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    tty->print_cr("%u %s "
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   203
                  SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   204
                  SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
                  id, space_names[id],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
                  summary_data().addr_to_chunk_idx(space->bottom()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
                  summary_data().addr_to_chunk_idx(space->top()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
                  summary_data().addr_to_chunk_idx(space->end()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
                  summary_data().addr_to_chunk_idx(_space_info[id].new_top()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
{
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   216
#define CHUNK_IDX_FORMAT        SIZE_FORMAT_W(7)
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   217
#define CHUNK_DATA_FORMAT       SIZE_FORMAT_W(5)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  tty->print_cr(CHUNK_IDX_FORMAT " " PTR_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
                CHUNK_IDX_FORMAT " " PTR_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
                CHUNK_DATA_FORMAT " " CHUNK_DATA_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
                CHUNK_DATA_FORMAT " " CHUNK_IDX_FORMAT " %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
                i, c->data_location(), dci, c->destination(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
                c->partial_obj_size(), c->live_obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
                c->data_size(), c->source_chunk(), c->destination_count());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
#undef  CHUNK_IDX_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
#undef  CHUNK_DATA_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
print_generic_summary_data(ParallelCompactData& summary_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
                           HeapWord* const beg_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
                           HeapWord* const end_addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  size_t total_words = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  size_t i = summary_data.addr_to_chunk_idx(beg_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  const size_t last = summary_data.addr_to_chunk_idx(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  HeapWord* pdest = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  while (i <= last) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    ParallelCompactData::ChunkData* c = summary_data.chunk(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    if (c->data_size() != 0 || c->destination() != pdest) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      print_generic_summary_chunk(i, c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      total_words += c->data_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      pdest = c->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    ++i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  tty->print_cr("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
print_generic_summary_data(ParallelCompactData& summary_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
                           SpaceInfo* space_info)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    const MutableSpace* space = space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    print_generic_summary_data(summary_data, space->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
                               MAX2(space->top(), space_info[id].new_top()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
print_initial_summary_chunk(size_t i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
                            const ParallelCompactData::ChunkData* c,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
                            bool newline = true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
{
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   272
  tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   273
             SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   274
             SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
             i, c->destination(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
             c->partial_obj_size(), c->live_obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
             c->data_size(), c->source_chunk(), c->destination_count());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  if (newline) tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
print_initial_summary_data(ParallelCompactData& summary_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
                           const MutableSpace* space) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  if (space->top() == space->bottom()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  HeapWord* const top_aligned_up = summary_data.chunk_align_up(space->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  const size_t end_chunk = summary_data.addr_to_chunk_idx(top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  const ParallelCompactData::ChunkData* c = summary_data.chunk(end_chunk - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  HeapWord* end_addr = c->destination() + c->data_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  const size_t live_in_space = pointer_delta(end_addr, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  // Print (and count) the full chunks at the beginning of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  size_t full_chunk_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  size_t i = summary_data.addr_to_chunk_idx(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  while (i < end_chunk && summary_data.chunk(i)->data_size() == chunk_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    print_initial_summary_chunk(i, summary_data.chunk(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    ++full_chunk_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    ++i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  size_t live_to_right = live_in_space - full_chunk_count * chunk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  double max_reclaimed_ratio = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  size_t max_reclaimed_ratio_chunk = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  size_t max_dead_to_right = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  size_t max_live_to_right = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  // Print the 'reclaimed ratio' for chunks while there is something live in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  // chunk or to the right of it.  The remaining chunks are empty (and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  // uninteresting), and computing the ratio will result in division by 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  while (i < end_chunk && live_to_right > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    c = summary_data.chunk(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    HeapWord* const chunk_addr = summary_data.chunk_to_addr(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    const size_t used_to_right = pointer_delta(space->top(), chunk_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    const size_t dead_to_right = used_to_right - live_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    const double reclaimed_ratio = double(dead_to_right) / live_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    if (reclaimed_ratio > max_reclaimed_ratio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
            max_reclaimed_ratio = reclaimed_ratio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
            max_reclaimed_ratio_chunk = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
            max_dead_to_right = dead_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
            max_live_to_right = live_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    print_initial_summary_chunk(i, c, false);
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   329
    tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
                  reclaimed_ratio, dead_to_right, live_to_right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    live_to_right -= c->data_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    ++i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // Any remaining chunks are empty.  Print one more if there is one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  if (i < end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    print_initial_summary_chunk(i, summary_data.chunk(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   341
  tty->print_cr("max:  " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
   342
                "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
                max_reclaimed_ratio_chunk, max_dead_to_right,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
                max_live_to_right, max_reclaimed_ratio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
print_initial_summary_data(ParallelCompactData& summary_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
                           SpaceInfo* space_info) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  unsigned int id = PSParallelCompact::perm_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  const MutableSpace* space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    space = space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    print_initial_summary_data(summary_data, space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  } while (++id < PSParallelCompact::eden_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    space = space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    print_generic_summary_data(summary_data, space->bottom(), space->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  } while (++id < PSParallelCompact::last_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
size_t add_obj_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
size_t add_obj_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
size_t mark_bitmap_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
size_t mark_bitmap_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
ParallelCompactData::ParallelCompactData()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  _region_start = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  _chunk_vspace = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  _chunk_data = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  _chunk_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  _block_vspace = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  _block_data = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  _block_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
bool ParallelCompactData::initialize(MemRegion covered_region)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  _region_start = covered_region.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  const size_t region_size = covered_region.word_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  DEBUG_ONLY(_region_end = _region_start + region_size;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  assert(chunk_align_down(_region_start) == _region_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
         "region start not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  assert((region_size & ChunkSizeOffsetMask) == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
         "region size not a multiple of ChunkSize");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  bool result = initialize_chunk_data(region_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // Initialize the block data if it will be used for updating pointers, or if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // this is a debug build.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  if (!UseParallelOldGCChunkPointerCalc || trueInDebug) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    result = result && initialize_block_data(region_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
PSVirtualSpace*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
ParallelCompactData::create_vspace(size_t count, size_t element_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  const size_t raw_bytes = count * element_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  const size_t granularity = os::vm_allocation_granularity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    MAX2(page_sz, granularity);
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 1
diff changeset
   416
  ReservedSpace rs(bytes, rs_align, rs_align > 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
                       rs.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  if (vspace != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    if (vspace->expand_by(bytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
      return vspace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    delete vspace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
bool ParallelCompactData::initialize_chunk_data(size_t region_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  const size_t count = (region_size + ChunkSizeOffsetMask) >> Log2ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  _chunk_vspace = create_vspace(count, sizeof(ChunkData));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  if (_chunk_vspace != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    _chunk_data = (ChunkData*)_chunk_vspace->reserved_low_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    _chunk_count = count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
bool ParallelCompactData::initialize_block_data(size_t region_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  const size_t count = (region_size + BlockOffsetMask) >> Log2BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  _block_vspace = create_vspace(count, sizeof(BlockData));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  if (_block_vspace != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    _block_data = (BlockData*)_block_vspace->reserved_low_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    _block_count = count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
void ParallelCompactData::clear()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  if (_block_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    memset(_block_data, 0, _block_vspace->committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  memset(_chunk_data, 0, _chunk_vspace->committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
void ParallelCompactData::clear_range(size_t beg_chunk, size_t end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  assert(beg_chunk <= _chunk_count, "beg_chunk out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  assert(end_chunk <= _chunk_count, "end_chunk out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  assert(ChunkSize % BlockSize == 0, "ChunkSize not a multiple of BlockSize");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  const size_t chunk_cnt = end_chunk - beg_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  if (_block_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
    const size_t blocks_per_chunk = ChunkSize / BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    const size_t beg_block = beg_chunk * blocks_per_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    const size_t block_cnt = chunk_cnt * blocks_per_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  memset(_chunk_data + beg_chunk, 0, chunk_cnt * sizeof(ChunkData));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
HeapWord* ParallelCompactData::partial_obj_end(size_t chunk_idx) const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  const ChunkData* cur_cp = chunk(chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  const ChunkData* const end_cp = chunk(chunk_count() - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  HeapWord* result = chunk_to_addr(chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  if (cur_cp < end_cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
      result += cur_cp->partial_obj_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    } while (cur_cp->partial_obj_size() == ChunkSize && ++cur_cp < end_cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
void ParallelCompactData::add_obj(HeapWord* addr, size_t len)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  const size_t obj_ofs = pointer_delta(addr, _region_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  const size_t beg_chunk = obj_ofs >> Log2ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  const size_t end_chunk = (obj_ofs + len - 1) >> Log2ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  DEBUG_ONLY(Atomic::inc_ptr(&add_obj_count);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  DEBUG_ONLY(Atomic::add_ptr(len, &add_obj_size);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  if (beg_chunk == end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    // All in one chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    _chunk_data[beg_chunk].add_live_obj(len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  // First chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  const size_t beg_ofs = chunk_offset(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  _chunk_data[beg_chunk].add_live_obj(ChunkSize - beg_ofs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  klassOop klass = ((oop)addr)->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  // Middle chunks--completely spanned by this object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  for (size_t chunk = beg_chunk + 1; chunk < end_chunk; ++chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
    _chunk_data[chunk].set_partial_obj_size(ChunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
    _chunk_data[chunk].set_partial_obj_addr(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // Last chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  const size_t end_ofs = chunk_offset(addr + len - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  _chunk_data[end_chunk].set_partial_obj_size(end_ofs + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  _chunk_data[end_chunk].set_partial_obj_addr(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
ParallelCompactData::summarize_dense_prefix(HeapWord* beg, HeapWord* end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  assert(chunk_offset(beg) == 0, "not ChunkSize aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  assert(chunk_offset(end) == 0, "not ChunkSize aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  size_t cur_chunk = addr_to_chunk_idx(beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  const size_t end_chunk = addr_to_chunk_idx(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  HeapWord* addr = beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  while (cur_chunk < end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    _chunk_data[cur_chunk].set_destination(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    _chunk_data[cur_chunk].set_destination_count(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    _chunk_data[cur_chunk].set_source_chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    _chunk_data[cur_chunk].set_data_location(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    // Update live_obj_size so the chunk appears completely full.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    size_t live_size = ChunkSize - _chunk_data[cur_chunk].partial_obj_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
    _chunk_data[cur_chunk].set_live_obj_size(live_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
    ++cur_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    addr += ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
bool ParallelCompactData::summarize(HeapWord* target_beg, HeapWord* target_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
                                    HeapWord* source_beg, HeapWord* source_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
                                    HeapWord** target_next,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
                                    HeapWord** source_next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  // This is too strict.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  // assert(chunk_offset(source_beg) == 0, "not ChunkSize aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  if (TraceParallelOldGCSummaryPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
    tty->print_cr("tb=" PTR_FORMAT " te=" PTR_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
                  "sb=" PTR_FORMAT " se=" PTR_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
                  "tn=" PTR_FORMAT " sn=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
                  target_beg, target_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
                  source_beg, source_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
                  target_next != 0 ? *target_next : (HeapWord*) 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
                  source_next != 0 ? *source_next : (HeapWord*) 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  size_t cur_chunk = addr_to_chunk_idx(source_beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  const size_t end_chunk = addr_to_chunk_idx(chunk_align_up(source_end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  HeapWord *dest_addr = target_beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  while (cur_chunk < end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    size_t words = _chunk_data[cur_chunk].data_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
#if     1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    assert(pointer_delta(target_end, dest_addr) >= words,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
           "source region does not fit into target region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    // XXX - need some work on the corner cases here.  If the chunk does not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    // fit, then must either make sure any partial_obj from the chunk fits, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
    // 'undo' the initial part of the partial_obj that is in the previous chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    if (dest_addr + words >= target_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      // Let the caller know where to continue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
      *target_next = dest_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
      *source_next = chunk_to_addr(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
#endif  // #if 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    _chunk_data[cur_chunk].set_destination(dest_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    // Set the destination_count for cur_chunk, and if necessary, update
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    // source_chunk for a destination chunk.  The source_chunk field is updated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    // if cur_chunk is the first (left-most) chunk to be copied to a destination
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    // chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    // The destination_count calculation is a bit subtle.  A chunk that has data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    // that compacts into itself does not count itself as a destination.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    // maintains the invariant that a zero count means the chunk is available
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    // and can be claimed and then filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    if (words > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
      HeapWord* const last_addr = dest_addr + words - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      const size_t dest_chunk_1 = addr_to_chunk_idx(dest_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      const size_t dest_chunk_2 = addr_to_chunk_idx(last_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
#if     0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      // Initially assume that the destination chunks will be the same and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      // adjust the value below if necessary.  Under this assumption, if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
      // cur_chunk == dest_chunk_2, then cur_chunk will be compacted completely
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      // into itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      uint destination_count = cur_chunk == dest_chunk_2 ? 0 : 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      if (dest_chunk_1 != dest_chunk_2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
        // Destination chunks differ; adjust destination_count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
        destination_count += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
        // Data from cur_chunk will be copied to the start of dest_chunk_2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
        _chunk_data[dest_chunk_2].set_source_chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
      } else if (chunk_offset(dest_addr) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
        // Data from cur_chunk will be copied to the start of the destination
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
        // chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
        _chunk_data[dest_chunk_1].set_source_chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
      // Initially assume that the destination chunks will be different and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
      // adjust the value below if necessary.  Under this assumption, if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
      // cur_chunk == dest_chunk2, then cur_chunk will be compacted partially
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
      // into dest_chunk_1 and partially into itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
      uint destination_count = cur_chunk == dest_chunk_2 ? 1 : 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
      if (dest_chunk_1 != dest_chunk_2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
        // Data from cur_chunk will be copied to the start of dest_chunk_2.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
        _chunk_data[dest_chunk_2].set_source_chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
        // Destination chunks are the same; adjust destination_count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
        destination_count -= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
        if (chunk_offset(dest_addr) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
          // Data from cur_chunk will be copied to the start of the destination
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
          // chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
          _chunk_data[dest_chunk_1].set_source_chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
#endif  // #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
      _chunk_data[cur_chunk].set_destination_count(destination_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      _chunk_data[cur_chunk].set_data_location(chunk_to_addr(cur_chunk));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
      dest_addr += words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    ++cur_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  *target_next = dest_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
bool ParallelCompactData::partial_obj_ends_in_block(size_t block_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  HeapWord* block_addr = block_to_addr(block_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  HeapWord* block_end_addr = block_addr + BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  size_t chunk_index = addr_to_chunk_idx(block_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  HeapWord* partial_obj_end_addr = partial_obj_end(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  // An object that ends at the end of the block, ends
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  // in the block (the last word of the object is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  // the left of the end).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  if ((block_addr < partial_obj_end_addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      (partial_obj_end_addr <= block_end_addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  HeapWord* result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  if (UseParallelOldGCChunkPointerCalc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    result = chunk_calc_new_pointer(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    result = block_calc_new_pointer(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
// This method is overly complicated (expensive) to be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
// for every reference.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
// Try to restructure this so that a NULL is returned if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
// the object is dead.  But don't wast the cycles to explicitly check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
// that it is dead since only live objects should be passed in.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
HeapWord* ParallelCompactData::chunk_calc_new_pointer(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  assert(addr != NULL, "Should detect NULL oop earlier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
  if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  // Chunk covering the object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  size_t chunk_index = addr_to_chunk_idx(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  const ChunkData* const chunk_ptr = chunk(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  HeapWord* const chunk_addr = chunk_align_down(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  assert(addr < chunk_addr + ChunkSize, "Chunk does not cover object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
  assert(addr_to_chunk_ptr(chunk_addr) == chunk_ptr, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  HeapWord* result = chunk_ptr->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  // If all the data in the chunk is live, then the new location of the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  // can be calculated from the destination of the chunk plus the offset of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  // object in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  if (chunk_ptr->data_size() == ChunkSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
    result += pointer_delta(addr, chunk_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  // The new location of the object is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  //    chunk destination +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  //    size of the partial object extending onto the chunk +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  //    sizes of the live objects in the Chunk that are to the left of addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  const size_t partial_obj_size = chunk_ptr->partial_obj_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  HeapWord* const search_start = chunk_addr + partial_obj_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  result += partial_obj_size + live_to_left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  assert(result <= addr, "object cannot move to the right");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
HeapWord* ParallelCompactData::block_calc_new_pointer(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  assert(addr != NULL, "Should detect NULL oop earlier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  // Chunk covering the object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  size_t chunk_index = addr_to_chunk_idx(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  const ChunkData* const chunk_ptr = chunk(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  HeapWord* const chunk_addr = chunk_align_down(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  assert(addr < chunk_addr + ChunkSize, "Chunk does not cover object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  assert(addr_to_chunk_ptr(chunk_addr) == chunk_ptr, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  HeapWord* result = chunk_ptr->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  // If all the data in the chunk is live, then the new location of the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  // can be calculated from the destination of the chunk plus the offset of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  // object in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  if (chunk_ptr->data_size() == ChunkSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
    result += pointer_delta(addr, chunk_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  // The new location of the object is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  //    chunk destination +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  //    block offset +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  //    sizes of the live objects in the Block that are to the left of addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  const size_t block_offset = addr_to_block_ptr(addr)->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  HeapWord* const search_start = chunk_addr + block_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  result += block_offset + live_to_left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
  assert(result <= addr, "object cannot move to the right");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  assert(result == chunk_calc_new_pointer(addr), "Should match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  klassOop updated_klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
  if (PSParallelCompact::should_update_klass(old_klass)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    updated_klass = (klassOop) calc_new_pointer(old_klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    updated_klass = old_klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  return updated_klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  const size_t* const beg = (const size_t*)vspace->committed_low_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  const size_t* const end = (const size_t*)vspace->committed_high_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
  for (const size_t* p = beg; p < end; ++p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    assert(*p == 0, "not zero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
void ParallelCompactData::verify_clear()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  verify_clear(_chunk_vspace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  verify_clear(_block_vspace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
#ifdef NOT_PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
ParallelCompactData::ChunkData* debug_chunk(size_t chunk_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  return sd.chunk(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
elapsedTimer        PSParallelCompact::_accumulated_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
unsigned int        PSParallelCompact::_total_invocations = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
unsigned int        PSParallelCompact::_maximum_compaction_gc_num = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
jlong               PSParallelCompact::_time_of_last_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
CollectorCounters*  PSParallelCompact::_counters = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
ParMarkBitMap       PSParallelCompact::_mark_bitmap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
ParallelCompactData PSParallelCompact::_summary_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
PSParallelCompact::IsAliveClosure PSParallelCompact::_is_alive_closure;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   814
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   815
void PSParallelCompact::IsAliveClosure::do_object(oop p)   { ShouldNotReachHere(); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   816
bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   817
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   818
void PSParallelCompact::KeepAliveClosure::do_oop(oop* p)       { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   819
void PSParallelCompact::KeepAliveClosure::do_oop(narrowOop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   820
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_root_pointer_closure(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   824
void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { adjust_pointer(p, _is_root); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   825
void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   826
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   827
void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   828
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   829
void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p)       { mark_and_push(_compaction_manager, p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
   830
void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
void PSParallelCompact::post_initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  MemRegion mr = heap->reserved_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  _ref_processor = ReferenceProcessor::create_ref_processor(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
    mr,                         // span
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
    true,                       // atomic_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    true,                       // mt_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
    &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    ParallelGCThreads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    ParallelRefProcEnabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  _counters = new CollectorCounters("PSParallelCompact", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  // Initialize static fields in ParCompactionManager.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
  ParCompactionManager::initialize(mark_bitmap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
bool PSParallelCompact::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  MemRegion mr = heap->reserved_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  // Was the old gen get allocated successfully?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  if (!heap->old_gen()->is_allocated()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
  initialize_space_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  initialize_dead_wood_limiter();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
  if (!_mark_bitmap.initialize(mr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
    vm_shutdown_during_initialization("Unable to allocate bit map for "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
      "parallel garbage collection for the requested heap size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  if (!_summary_data.initialize(mr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    vm_shutdown_during_initialization("Unable to allocate tables for "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
      "parallel garbage collection for the requested heap size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
void PSParallelCompact::initialize_space_info()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
  memset(&_space_info, 0, sizeof(_space_info));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  MutableSpace* perm_space = heap->perm_gen()->object_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  _space_info[perm_space_id].set_space(perm_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  _space_info[old_space_id].set_space(heap->old_gen()->object_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
  _space_info[eden_space_id].set_space(young_gen->eden_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  _space_info[from_space_id].set_space(young_gen->from_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  _space_info[to_space_id].set_space(young_gen->to_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  _space_info[perm_space_id].set_start_array(heap->perm_gen()->start_array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  _space_info[old_space_id].set_start_array(heap->old_gen()->start_array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  _space_info[perm_space_id].set_min_dense_prefix(perm_space->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  if (TraceParallelOldGCDensePrefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
    tty->print_cr("perm min_dense_prefix=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
                  _space_info[perm_space_id].min_dense_prefix());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
void PSParallelCompact::initialize_dead_wood_limiter()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
  const size_t max = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  _dwl_mean = double(MIN2(ParallelOldDeadWoodLimiterMean, max)) / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  _dwl_std_dev = double(MIN2(ParallelOldDeadWoodLimiterStdDev, max)) / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  _dwl_first_term = 1.0 / (sqrt(2.0 * M_PI) * _dwl_std_dev);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  DEBUG_ONLY(_dwl_initialized = true;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  _dwl_adjustment = normal_distribution(1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
// Simple class for storing info about the heap at the start of GC, to be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
// after GC for comparison/printing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
class PreGCValues {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  PreGCValues() { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  PreGCValues(ParallelScavengeHeap* heap) { fill(heap); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  void fill(ParallelScavengeHeap* heap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    _heap_used      = heap->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    _young_gen_used = heap->young_gen()->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    _old_gen_used   = heap->old_gen()->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
    _perm_gen_used  = heap->perm_gen()->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  size_t heap_used() const      { return _heap_used; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  size_t young_gen_used() const { return _young_gen_used; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
  size_t old_gen_used() const   { return _old_gen_used; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
  size_t perm_gen_used() const  { return _perm_gen_used; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  size_t _heap_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  size_t _young_gen_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
  size_t _old_gen_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  size_t _perm_gen_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
PSParallelCompact::clear_data_covering_space(SpaceId id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  // At this point, top is the value before GC, new_top() is the value that will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  // be set at the end of GC.  The marking bitmap is cleared to top; nothing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  // should be marked above top.  The summary data is cleared to the larger of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  // top & new_top.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  MutableSpace* const space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
  HeapWord* const bot = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  HeapWord* const top = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  HeapWord* const max_top = MAX2(top, _space_info[id].new_top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  const idx_t beg_bit = _mark_bitmap.addr_to_bit(bot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  const idx_t end_bit = BitMap::word_align_up(_mark_bitmap.addr_to_bit(top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  _mark_bitmap.clear_range(beg_bit, end_bit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  const size_t beg_chunk = _summary_data.addr_to_chunk_idx(bot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  const size_t end_chunk =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    _summary_data.addr_to_chunk_idx(_summary_data.chunk_align_up(max_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
  _summary_data.clear_range(beg_chunk, end_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  // Update the from & to space pointers in space_info, since they are swapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  // at each young gen gc.  Do the update unconditionally (even though a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  // promotion failure does not swap spaces) because an unknown number of minor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  // collections will have swapped the spaces an unknown number of times.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  TraceTime tm("pre compact", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  _space_info[from_space_id].set_space(heap->young_gen()->from_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  _space_info[to_space_id].set_space(heap->young_gen()->to_space());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  pre_gc_values->fill(heap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  ParCompactionManager::reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  NOT_PRODUCT(_mark_bitmap.reset_counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
  DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
  // Increment the invocation count
386
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
   979
  heap->increment_total_collections(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  // We need to track unique mark sweep invocations as well.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  _total_invocations++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  if (PrintHeapAtGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
    Universe::print_heap_before_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  // Fill in TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
  heap->accumulate_statistics_all_tlabs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  heap->ensure_parsability(true);  // retire TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    gclog_or_tty->print(" VerifyBeforeGC:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  // Verify object start arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  if (VerifyObjectStartArray &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
      VerifyBeforeGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    heap->old_gen()->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
    heap->perm_gen()->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  DEBUG_ONLY(mark_bitmap()->verify_clear();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  DEBUG_ONLY(summary_data().verify_clear();)
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1007
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1008
  // Have worker threads release resources the next time they run a task.
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1009
  gc_task_manager()->release_all_resources();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
void PSParallelCompact::post_compact()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  TraceTime tm("post compact", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  // Clear the marking bitmap and summary data and update top() in each space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
  for (unsigned int id = perm_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
    clear_data_covering_space(SpaceId(id));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
    _space_info[id].space()->set_top(_space_info[id].new_top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  MutableSpace* const eden_space = _space_info[eden_space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  MutableSpace* const from_space = _space_info[from_space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  MutableSpace* const to_space   = _space_info[to_space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
  bool eden_empty = eden_space->is_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
  if (!eden_empty) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    eden_empty = absorb_live_data_from_eden(heap->size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
                                            heap->young_gen(), heap->old_gen());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
  // Update heap occupancy information which is used as input to the soft ref
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  // clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
  Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  bool young_gen_empty = eden_empty && from_space->is_empty() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    to_space->is_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  BarrierSet* bs = heap->barrier_set();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  if (bs->is_a(BarrierSet::ModRef)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
    ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
    MemRegion old_mr = heap->old_gen()->reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
    MemRegion perm_mr = heap->perm_gen()->reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
    assert(perm_mr.end() <= old_mr.start(), "Generations out of order");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
    if (young_gen_empty) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
      modBS->clear(MemRegion(perm_mr.start(), old_mr.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
      modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  Threads::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  CodeCache::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
  ref_processor()->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1061
  if (ZapUnusedHeapArea) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1062
    heap->gen_mangle_unused_area();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1063
  }
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1064
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
  // Update time of last GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
  reset_millis_since_last_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
                                                    bool maximum_compaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
  const ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  const MutableSpace* const space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
  HeapWord* const top_aligned_up = sd.chunk_align_up(space->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  const ChunkData* const beg_cp = sd.addr_to_chunk_ptr(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  const ChunkData* const end_cp = sd.addr_to_chunk_ptr(top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  // Skip full chunks at the beginning of the space--they are necessarily part
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
  // of the dense prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
  size_t full_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  const ChunkData* cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  for (cp = beg_cp; cp < end_cp && cp->data_size() == chunk_size; ++cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
    ++full_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
  const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
  if (maximum_compaction || cp == end_cp || interval_ended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
    _maximum_compaction_gc_num = total_invocations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
    return sd.chunk_to_addr(cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  HeapWord* const new_top = _space_info[id].new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  const size_t space_live = pointer_delta(new_top, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  const size_t space_used = space->used_in_words();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  const size_t space_capacity = space->capacity_in_words();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  const double cur_density = double(space_live) / space_capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
  const double deadwood_density =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
    (1.0 - cur_density) * (1.0 - cur_density) * cur_density * cur_density;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  const size_t deadwood_goal = size_t(space_capacity * deadwood_density);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  if (TraceParallelOldGCDensePrefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    tty->print_cr("cur_dens=%5.3f dw_dens=%5.3f dw_goal=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
                  cur_density, deadwood_density, deadwood_goal);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
                  "space_cap=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
                  space_live, space_used,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
                  space_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
  // XXX - Use binary search?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  HeapWord* dense_prefix = sd.chunk_to_addr(cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
  const ChunkData* full_cp = cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  const ChunkData* const top_cp = sd.addr_to_chunk_ptr(space->top() - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  while (cp < end_cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
    HeapWord* chunk_destination = cp->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
    const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
    if (TraceParallelOldGCDensePrefix && Verbose) {
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
  1124
      tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
  1125
                    "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
                    sd.chunk(cp), chunk_destination,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
                    dense_prefix, cur_deadwood);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    if (cur_deadwood >= deadwood_goal) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
      // Found the chunk that has the correct amount of deadwood to the left.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
      // This typically occurs after crossing a fairly sparse set of chunks, so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
      // iterate backwards over those sparse chunks, looking for the chunk that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
      // has the lowest density of live objects 'to the right.'
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
      size_t space_to_left = sd.chunk(cp) * chunk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
      size_t live_to_left = space_to_left - cur_deadwood;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
      size_t space_to_right = space_capacity - space_to_left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
      size_t live_to_right = space_live - live_to_left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
      double density_to_right = double(live_to_right) / space_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
      while (cp > full_cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
        --cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
        const size_t prev_chunk_live_to_right = live_to_right - cp->data_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
        const size_t prev_chunk_space_to_right = space_to_right + chunk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
        double prev_chunk_density_to_right =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
          double(prev_chunk_live_to_right) / prev_chunk_space_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
        if (density_to_right <= prev_chunk_density_to_right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
          return dense_prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
        if (TraceParallelOldGCDensePrefix && Verbose) {
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
  1150
          tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
                        "pc_d2r=%10.8f", sd.chunk(cp), density_to_right,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
                        prev_chunk_density_to_right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
        dense_prefix -= chunk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
        live_to_right = prev_chunk_live_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
        space_to_right = prev_chunk_space_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
        density_to_right = prev_chunk_density_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
      return dense_prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    dense_prefix += chunk_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
    ++cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  return dense_prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
                                                 const SpaceId id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
                                                 const bool maximum_compaction,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
                                                 HeapWord* const addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  const size_t chunk_idx = summary_data().addr_to_chunk_idx(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  ChunkData* const cp = summary_data().chunk(chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  const MutableSpace* const space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  HeapWord* const new_top = _space_info[id].new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  const size_t space_live = pointer_delta(new_top, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  const size_t dead_to_left = pointer_delta(addr, cp->destination());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  const size_t space_cap = space->capacity_in_words();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  const double dead_to_left_pct = double(dead_to_left) / space_cap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  const size_t live_to_right = new_top - cp->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
  const size_t dead_to_right = space->top() - addr - live_to_right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
  1187
  tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " "
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
                "spl=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
                "d2l=" SIZE_FORMAT " d2l%%=%6.4f "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
                "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
                " ratio=%10.8f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
                algorithm, addr, chunk_idx,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
                space_live,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
                dead_to_left, dead_to_left_pct,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
                dead_to_right, live_to_right,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
                double(dead_to_right) / live_to_right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
// Return a fraction indicating how much of the generation can be treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
// "dead wood" (i.e., not reclaimed).  The function uses a normal distribution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
// based on the density of live objects in the generation to determine a limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
// which is then adjusted so the return value is min_percent when the density is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
// 1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
// The following table shows some return values for a different values of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
// standard deviation (ParallelOldDeadWoodLimiterStdDev); the mean is 0.5 and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
// min_percent is 1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
//                          fraction allowed as dead wood
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
//         -----------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
// density std_dev=70 std_dev=75 std_dev=80 std_dev=85 std_dev=90 std_dev=95
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
// ------- ---------- ---------- ---------- ---------- ---------- ----------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
// 0.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
// 0.05000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
// 0.10000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
// 0.15000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
// 0.20000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
// 0.25000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
// 0.30000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
// 0.35000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
// 0.40000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
// 0.45000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
// 0.50000 0.13832410 0.11599237 0.09847664 0.08456518 0.07338887 0.06431510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
// 0.55000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
// 0.60000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
// 0.65000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
// 0.70000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
// 0.75000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
// 0.80000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
// 0.85000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
// 0.90000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
// 0.95000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
// 1.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
double PSParallelCompact::dead_wood_limiter(double density, size_t min_percent)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
  assert(_dwl_initialized, "uninitialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  // The raw limit is the value of the normal distribution at x = density.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
  const double raw_limit = normal_distribution(density);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
  // Adjust the raw limit so it becomes the minimum when the density is 1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
  // First subtract the adjustment value (which is simply the precomputed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
  // normal_distribution(1.0)); this yields a value of 0 when the density is 1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
  // Then add the minimum value, so the minimum is returned when the density is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
  // 1.  Finally, prevent negative values, which occur when the mean is not 0.5.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  const double min = double(min_percent) / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  const double limit = raw_limit - _dwl_adjustment + min;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
  return MAX2(limit, 0.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
ParallelCompactData::ChunkData*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
PSParallelCompact::first_dead_space_chunk(const ChunkData* beg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
                                          const ChunkData* end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  size_t left = sd.chunk(beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  size_t right = end > beg ? sd.chunk(end) - 1 : left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
  // Binary search.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  while (left < right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
    // Equivalent to (left + right) / 2, but does not overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
    const size_t middle = left + (right - left) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
    ChunkData* const middle_ptr = sd.chunk(middle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
    HeapWord* const dest = middle_ptr->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    HeapWord* const addr = sd.chunk_to_addr(middle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
    assert(dest != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
    assert(dest <= addr, "must move left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
    if (middle > left && dest < addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
      right = middle - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
    } else if (middle < right && middle_ptr->data_size() == chunk_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
      left = middle + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
      return middle_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
  return sd.chunk(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
ParallelCompactData::ChunkData*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
PSParallelCompact::dead_wood_limit_chunk(const ChunkData* beg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
                                         const ChunkData* end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
                                         size_t dead_words)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  size_t left = sd.chunk(beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  size_t right = end > beg ? sd.chunk(end) - 1 : left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // Binary search.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  while (left < right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
    // Equivalent to (left + right) / 2, but does not overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
    const size_t middle = left + (right - left) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
    ChunkData* const middle_ptr = sd.chunk(middle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    HeapWord* const dest = middle_ptr->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    HeapWord* const addr = sd.chunk_to_addr(middle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    assert(dest != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
    assert(dest <= addr, "must move left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    const size_t dead_to_left = pointer_delta(addr, dest);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
    if (middle > left && dead_to_left > dead_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
      right = middle - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    } else if (middle < right && dead_to_left < dead_words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
      left = middle + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
      return middle_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  return sd.chunk(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
// The result is valid during the summary phase, after the initial summarization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
// of each space into itself, and before final summarization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
inline double
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
PSParallelCompact::reclaimed_ratio(const ChunkData* const cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
                                   HeapWord* const bottom,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
                                   HeapWord* const top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
                                   HeapWord* const new_top)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  assert(cp != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  assert(bottom != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
  assert(top != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
  assert(new_top != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
  assert(top >= new_top, "summary data problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
  assert(new_top > bottom, "space is empty; should not be here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
  assert(new_top >= cp->destination(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
  assert(top >= sd.chunk_to_addr(cp), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  HeapWord* const destination = cp->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  const size_t dense_prefix_live  = pointer_delta(destination, bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  const size_t compacted_region_live = pointer_delta(new_top, destination);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  const size_t compacted_region_used = pointer_delta(top, sd.chunk_to_addr(cp));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
  const size_t reclaimable = compacted_region_used - compacted_region_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  const double divisor = dense_prefix_live + 1.25 * compacted_region_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
  return double(reclaimable) / divisor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
// Return the address of the end of the dense prefix, a.k.a. the start of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
// compacted region.  The address is always on a chunk boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
// Completely full chunks at the left are skipped, since no compaction can occur
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
// in those chunks.  Then the maximum amount of dead wood to allow is computed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
// based on the density (amount live / capacity) of the generation; the chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
// with approximately that amount of dead space to the left is identified as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
// limit chunk.  Chunks between the last completely full chunk and the limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
// chunk are scanned and the one that has the best (maximum) reclaimed_ratio()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
// is selected.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
PSParallelCompact::compute_dense_prefix(const SpaceId id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
                                        bool maximum_compaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  const ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  const MutableSpace* const space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
  HeapWord* const top = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  HeapWord* const top_aligned_up = sd.chunk_align_up(top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  HeapWord* const new_top = _space_info[id].new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  HeapWord* const new_top_aligned_up = sd.chunk_align_up(new_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  HeapWord* const bottom = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  const ChunkData* const beg_cp = sd.addr_to_chunk_ptr(bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  const ChunkData* const top_cp = sd.addr_to_chunk_ptr(top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  const ChunkData* const new_top_cp = sd.addr_to_chunk_ptr(new_top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  // Skip full chunks at the beginning of the space--they are necessarily part
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  // of the dense prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  const ChunkData* const full_cp = first_dead_space_chunk(beg_cp, new_top_cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  assert(full_cp->destination() == sd.chunk_to_addr(full_cp) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
         space->is_empty(), "no dead space allowed to the left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  assert(full_cp->data_size() < chunk_size || full_cp == new_top_cp - 1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
         "chunk must have dead space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  // The gc number is saved whenever a maximum compaction is done, and used to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  // determine when the maximum compaction interval has expired.  This avoids
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  // successive max compactions for different reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
    total_invocations() == HeapFirstMaximumCompactionCount;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  if (maximum_compaction || full_cp == top_cp || interval_ended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
    _maximum_compaction_gc_num = total_invocations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
    return sd.chunk_to_addr(full_cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  const size_t space_live = pointer_delta(new_top, bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  const size_t space_used = space->used_in_words();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
  const size_t space_capacity = space->capacity_in_words();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  const double density = double(space_live) / double(space_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  const size_t min_percent_free =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
          id == perm_space_id ? PermMarkSweepDeadRatio : MarkSweepDeadRatio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  const double limiter = dead_wood_limiter(density, min_percent_free);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  const size_t dead_wood_max = space_used - space_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  const size_t dead_wood_limit = MIN2(size_t(space_capacity * limiter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
                                      dead_wood_max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
  if (TraceParallelOldGCDensePrefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
    tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
                  "space_cap=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
                  space_live, space_used,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
                  space_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
    tty->print_cr("dead_wood_limiter(%6.4f, %d)=%6.4f "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
                  "dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
                  density, min_percent_free, limiter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
                  dead_wood_max, dead_wood_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
  // Locate the chunk with the desired amount of dead space to the left.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
  const ChunkData* const limit_cp =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
    dead_wood_limit_chunk(full_cp, top_cp, dead_wood_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
  // Scan from the first chunk with dead space to the limit chunk and find the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  // one with the best (largest) reclaimed ratio.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
  double best_ratio = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
  const ChunkData* best_cp = full_cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
  for (const ChunkData* cp = full_cp; cp < limit_cp; ++cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
    double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
    if (tmp_ratio > best_ratio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      best_cp = cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
      best_ratio = tmp_ratio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
#if     0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
  // Something to consider:  if the chunk with the best ratio is 'close to' the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  // first chunk w/free space, choose the first chunk with free space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  // ("first-free").  The first-free chunk is usually near the start of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  // heap, which means we are copying most of the heap already, so copy a bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
  // more to get complete compaction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  if (pointer_delta(best_cp, full_cp, sizeof(ChunkData)) < 4) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
    _maximum_compaction_gc_num = total_invocations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
    best_cp = full_cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
#endif  // #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  return sd.chunk_to_addr(best_cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
void PSParallelCompact::summarize_spaces_quick()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
  for (unsigned int i = 0; i < last_space_id; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
    const MutableSpace* space = _space_info[i].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
    bool result = _summary_data.summarize(space->bottom(), space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
                                          space->bottom(), space->top(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
                                          _space_info[i].new_top_addr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
    assert(result, "should never fail");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
    _space_info[i].set_dense_prefix(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
void PSParallelCompact::fill_dense_prefix_end(SpaceId id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
  HeapWord* const dense_prefix_end = dense_prefix(id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  const ChunkData* chunk = _summary_data.addr_to_chunk_ptr(dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
  const idx_t dense_prefix_bit = _mark_bitmap.addr_to_bit(dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  if (dead_space_crosses_boundary(chunk, dense_prefix_bit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
    // Only enough dead space is filled so that any remaining dead space to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
    // left is larger than the minimum filler object.  (The remainder is filled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    // during the copy/update phase.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
    // The size of the dead space to the right of the boundary is not a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
    // concern, since compaction will be able to use whatever space is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
    // available.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
    // Here '||' is the boundary, 'x' represents a don't care bit and a box
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
    // surrounds the space to be filled with an object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
    // In the 32-bit VM, each bit represents two 32-bit words:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
    //                              +---+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
    // a) beg_bits:  ...  x   x   x | 0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
    //    end_bits:  ...  x   x   x | 0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
    //                              +---+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    // In the 64-bit VM, each bit represents one 64-bit word:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
    //                              +------------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
    // b) beg_bits:  ...  x   x   x | 0   ||   0 | x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
    //    end_bits:  ...  x   x   1 | 0   ||   0 | x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
    //                              +------------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
    //                          +-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
    // c) beg_bits:  ...  x   x | 0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
    //    end_bits:  ...  x   1 | 0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
    //                          +-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
    //                      +-----------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
    // d) beg_bits:  ...  x | 0   0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
    //    end_bits:  ...  1 | 0   0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
    //                      +-----------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
    //                          +-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
    // e) beg_bits:  ...  0   0 | 0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    //    end_bits:  ...  0   0 | 0   0 | ||   0   x  x  ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
    //                          +-------+
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
    // Initially assume case a, c or e will apply.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
    size_t obj_len = (size_t)oopDesc::header_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
    HeapWord* obj_beg = dense_prefix_end - obj_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
#ifdef  _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
    if (_mark_bitmap.is_obj_end(dense_prefix_bit - 2)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
      // Case b above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
      obj_beg = dense_prefix_end - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
    } else if (!_mark_bitmap.is_obj_end(dense_prefix_bit - 3) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
               _mark_bitmap.is_obj_end(dense_prefix_bit - 4)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
      // Case d above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
      obj_beg = dense_prefix_end - 3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
      obj_len = 3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
#endif  // #ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
    MemRegion region(obj_beg, obj_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
    SharedHeap::fill_region_with_object(region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
    _mark_bitmap.mark_obj(obj_beg, obj_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
    _summary_data.add_obj(obj_beg, obj_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
    assert(start_array(id) != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
    start_array(id)->allocate_block(obj_beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
  assert(id < last_space_id, "id out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
  const MutableSpace* space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
  HeapWord** new_top_addr = _space_info[id].new_top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
  HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
  _space_info[id].set_dense_prefix(dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
  if (TraceParallelOldGCDensePrefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
    print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
    HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
    print_dense_prefix_stats("density", id, maximum_compaction, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
  // If dead space crosses the dense prefix boundary, it is (at least partially)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  // filled with a dummy object, marked live and added to the summary data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  // This simplifies the copy/update phase and must be done before the final
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
  // locations of objects are determined, to prevent leaving a fragment of dead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
  // space that is too small to fill with an object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  if (!maximum_compaction && dense_prefix_end != space->bottom()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
    fill_dense_prefix_end(id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  // Compute the destination of each Chunk, and thus each object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  _summary_data.summarize(dense_prefix_end, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
                          dense_prefix_end, space->top(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
                          new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
  if (TraceParallelOldGCSummaryPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
    const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
    const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
    tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
                  "dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
                  "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
                  id, space->capacity_in_words(), dense_prefix_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
                  dp_chunk, dp_words / chunk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
                  cr_words / chunk_size, *new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
void PSParallelCompact::summary_phase(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
                                      bool maximum_compaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
  EventMark m("2 summarize");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
  TraceTime tm("summary phase", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  // trace("2");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
  if (VerifyParallelOldWithMarkSweep  &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
      (PSParallelCompact::total_invocations() %
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
         VerifyParallelOldWithMarkSweepInterval) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
    verify_mark_bitmap(_mark_bitmap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  if (TraceParallelOldGCMarkingPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
    tty->print_cr("add_obj_count=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
                  "add_obj_bytes=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
                  add_obj_count, add_obj_size * HeapWordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
    tty->print_cr("mark_bitmap_count=" SIZE_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
                  "mark_bitmap_bytes=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
                  mark_bitmap_count, mark_bitmap_size * HeapWordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
  // Quick summarization of each space into itself, to see how much is live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
  summarize_spaces_quick();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
  if (TraceParallelOldGCSummaryPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
    tty->print_cr("summary_phase:  after summarizing each space to self");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
    Universe::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
    NOT_PRODUCT(print_chunk_ranges());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
      NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  // The amount of live data that will end up in old space (assuming it fits).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
  size_t old_space_total_live = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  unsigned int id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  for (id = old_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
    old_space_total_live += pointer_delta(_space_info[id].new_top(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
                                          _space_info[id].space()->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
  const MutableSpace* old_space = _space_info[old_space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
  if (old_space_total_live > old_space->capacity_in_words()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
    // XXX - should also try to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
    maximum_compaction = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
  } else if (!UseParallelOldGCDensePrefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
    maximum_compaction = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
  // Permanent and Old generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
  summarize_space(perm_space_id, maximum_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
  summarize_space(old_space_id, maximum_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
  // Summarize the remaining spaces (those in the young gen) into old space.  If
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
  // the live data from a space doesn't fit, the existing summarization is left
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
  // intact, so the data is compacted down within the space itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
  HeapWord** new_top_addr = _space_info[old_space_id].new_top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
  HeapWord* const target_space_end = old_space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
  for (id = eden_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
    const MutableSpace* space = _space_info[id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
    const size_t live = pointer_delta(_space_info[id].new_top(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
                                      space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
    const size_t available = pointer_delta(target_space_end, *new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
    if (live <= available) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
      // All the live data will fit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
      if (TraceParallelOldGCSummaryPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
        tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
                      id, *new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
      _summary_data.summarize(*new_top_addr, target_space_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
                              space->bottom(), space->top(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
                              new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
      // Reset the new_top value for the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
      _space_info[id].set_new_top(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
      // Clear the source_chunk field for each chunk in the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
      ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
      ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
      while (beg_chunk <= end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
        beg_chunk->set_source_chunk(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
        ++beg_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
  // Fill in the block data after any changes to the chunks have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
  // been made.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
  summarize_blocks(cm, perm_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
  summarize_blocks(cm, old_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
  if (!UseParallelOldGCChunkPointerCalc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
    summarize_blocks(cm, perm_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
    summarize_blocks(cm, old_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  if (TraceParallelOldGCSummaryPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
    tty->print_cr("summary_phase:  after final summarization");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
    Universe::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
    NOT_PRODUCT(print_chunk_ranges());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
      NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
// Fill in the BlockData.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
// Iterate over the spaces and within each space iterate over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
// the chunks and fill in the BlockData for each chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
void PSParallelCompact::summarize_blocks(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
                                         SpaceId first_compaction_space_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
#if     0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(1);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
  for (SpaceId cur_space_id = first_compaction_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
       cur_space_id != last_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
       cur_space_id = next_compaction_space_id(cur_space_id)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
    // Iterate over the chunks in the space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
    size_t start_chunk_index =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
      _summary_data.addr_to_chunk_idx(space(cur_space_id)->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
    BitBlockUpdateClosure bbu(mark_bitmap(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
                              cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
                              start_chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
    // Iterate over blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
    for (size_t chunk_index =  start_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
         chunk_index < _summary_data.chunk_count() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
         _summary_data.chunk_to_addr(chunk_index) < space(cur_space_id)->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
         chunk_index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
      // Reset the closure for the new chunk.  Note that the closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
      // maintains some data that does not get reset for each chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
      // so a new instance of the closure is no appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
      bbu.reset_chunk(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
      // Start the iteration with the first live object.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
      // may return the end of the chunk.  That is acceptable since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
      // it will properly limit the iterations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
      ParMarkBitMap::idx_t left_offset = mark_bitmap()->addr_to_bit(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
        _summary_data.first_live_or_end_in_chunk(chunk_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
      // End the iteration at the end of the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
      HeapWord* chunk_addr = _summary_data.chunk_to_addr(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
      HeapWord* chunk_end = chunk_addr + ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
      ParMarkBitMap::idx_t right_offset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
        mark_bitmap()->addr_to_bit(chunk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
      // Blocks that have not objects starting in them can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
      // skipped because their data will never be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
      if (left_offset < right_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
        // Iterate through the objects in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
        ParMarkBitMap::idx_t last_offset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
          mark_bitmap()->pair_iterate(&bbu, left_offset, right_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
        // If last_offset is less than right_offset, then the iterations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
        // terminated while it was looking for an end bit.  "last_offset"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
        // is then the offset for the last start bit.  In this situation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
        // the "offset" field for the next block to the right (_cur_block + 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
        // will not have been update although there may be live data
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
        // to the left of the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
        size_t cur_block_plus_1 = bbu.cur_block() + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
        HeapWord* cur_block_plus_1_addr =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
        _summary_data.block_to_addr(bbu.cur_block()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
        ParallelCompactData::BlockSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
        HeapWord* last_offset_addr = mark_bitmap()->bit_to_addr(last_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
 #if 1  // This code works.  The else doesn't but should.  Why does it?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
        // The current block (cur_block()) has already been updated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
        // The last block that may need to be updated is either the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
        // next block (current block + 1) or the block where the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
        // last object starts (which can be greater than the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
        // next block if there were no objects found in intervening
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
        // blocks).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
        size_t last_block =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
          MAX2(bbu.cur_block() + 1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
               _summary_data.addr_to_block_idx(last_offset_addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
 #else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
        // The current block has already been updated.  The only block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
        // that remains to be updated is the block where the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
        // object in the chunk starts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
        size_t last_block = _summary_data.addr_to_block_idx(last_offset_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
 #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
        assert_bit_is_start(last_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
        assert((last_block == _summary_data.block_count()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
             (_summary_data.block(last_block)->raw_offset() == 0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
          "Should not have been set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
        // Is the last block still in the current chunk?  If still
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
        // in this chunk, update the last block (the counting that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
        // included the current block is meant for the offset of the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
        // block).  If not in this chunk, do nothing.  Should not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
        // update a block in the next chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
        if (ParallelCompactData::chunk_contains_block(bbu.chunk_index(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
                                                      last_block)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
          if (last_offset < right_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
            // The last object started in this chunk but ends beyond
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
            // this chunk.  Update the block for this last object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
            assert(mark_bitmap()->is_marked(last_offset), "Should be marked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
            // No end bit was found.  The closure takes care of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
            // the cases where
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
            //   an objects crosses over into the next block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
            //   an objects starts and ends in the next block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
            // It does not handle the case where an object is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
            // the first object in a later block and extends
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
            // past the end of the chunk (i.e., the closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
            // only handles complete objects that are in the range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
            // it is given).  That object is handed back here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
            // for any special consideration necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
            //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
            // Is the first bit in the last block a start or end bit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
            //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
            // If the partial object ends in the last block L,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
            // then the 1st bit in L may be an end bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
            //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
            // Else does the last object start in a block after the current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
            // block? A block AA will already have been updated if an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
            // object ends in the next block AA+1.  An object found to end in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
            // the AA+1 is the trigger that updates AA.  Objects are being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
            // counted in the current block for updaing a following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
            // block.  An object may start in later block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
            // block but may extend beyond the last block in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
            // Updates are only done when the end of an object has been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
            // found. If the last object (covered by block L) starts
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
            // beyond the current block, then no object ends in L (otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
            // L would be the current block).  So the first bit in L is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
            // a start bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
            //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
            // Else the last objects start in the current block and ends
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
            // beyond the chunk.  The current block has already been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
            // updated and there is no later block (with an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
            // starting in it) that needs to be updated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
            //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
            if (_summary_data.partial_obj_ends_in_block(last_block)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
              _summary_data.block(last_block)->set_end_bit_offset(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
                bbu.live_data_left());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
            } else if (last_offset_addr >= cur_block_plus_1_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
              //   The start of the object is on a later block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
              // (to the right of the current block and there are no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
              // complete live objects to the left of this last object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
              // within the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
              //   The first bit in the block is for the start of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
              // last object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
              _summary_data.block(last_block)->set_start_bit_offset(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
                bbu.live_data_left());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
              //   The start of the last object was found in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
              // the current chunk (which has already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
              // been updated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
              assert(bbu.cur_block() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
                      _summary_data.addr_to_block_idx(last_offset_addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
                "Should be a block already processed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
            // Is there enough block information to find this object?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
            // The destination of the chunk has not been set so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
            // values returned by calc_new_pointer() and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
            // block_calc_new_pointer() will only be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
            // offsets.  But they should agree.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
            HeapWord* moved_obj_with_chunks =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
              _summary_data.chunk_calc_new_pointer(last_offset_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
            HeapWord* moved_obj_with_blocks =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
              _summary_data.calc_new_pointer(last_offset_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
            assert(moved_obj_with_chunks == moved_obj_with_blocks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
              "Block calculation is wrong");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
          } else if (last_block < _summary_data.block_count()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
            // Iterations ended looking for a start bit (but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
            // did not run off the end of the block table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
            _summary_data.block(last_block)->set_start_bit_offset(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
              bbu.live_data_left());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
        // Is there enough block information to find this object?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
          HeapWord* left_offset_addr = mark_bitmap()->bit_to_addr(left_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
        HeapWord* moved_obj_with_chunks =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
          _summary_data.calc_new_pointer(left_offset_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
        HeapWord* moved_obj_with_blocks =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
          _summary_data.calc_new_pointer(left_offset_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
          assert(moved_obj_with_chunks == moved_obj_with_blocks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
          "Block calculation is wrong");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
        // Is there another block after the end of this chunk?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
        if (last_block < _summary_data.block_count()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
        // No object may have been found in a block.  If that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
        // block is at the end of the chunk, the iteration will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
        // terminate without incrementing the current block so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
        // that the current block is not the last block in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
        // chunk.  That situation precludes asserting that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
        // current block is the last block in the chunk.  Assert
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
        // the lesser condition that the current block does not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
        // exceed the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
          assert(_summary_data.block_to_addr(last_block) <=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
               (_summary_data.chunk_to_addr(chunk_index) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
                 ParallelCompactData::ChunkSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
              "Chunk and block inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
          assert(last_offset <= right_offset, "Iteration over ran end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
      if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
        if (_summary_data.chunk(chunk_index)->partial_obj_size() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
          size_t first_block =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
            chunk_index / ParallelCompactData::BlocksPerChunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
          gclog_or_tty->print_cr("first_block " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
            " _offset " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
            "_first_is_start_bit %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
            first_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
            _summary_data.block(first_block)->raw_offset(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
            _summary_data.block(first_block)->first_is_start_bit());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(16);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
#endif  // #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
// This method should contain all heap-specific policy for invoking a full
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
// collection.  invoke_no_policy() will only attempt to compact the heap; it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
// will do nothing further.  If we need to bail out for policy reasons, scavenge
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
// before full gc, or any other specialized behavior, it needs to be added here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
// Note that this method should only be called from the vm_thread while at a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
// safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
void PSParallelCompact::invoke(bool maximum_heap_compaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
  assert(Thread::current() == (Thread*)VMThread::vm_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
         "should be in vm thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  GCCause::Cause gc_cause = heap->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  assert(!heap->is_gc_active(), "not reentrant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  PSAdaptiveSizePolicy* policy = heap->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  // Before each allocation/collection attempt, find out from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
  // policy object if GCs are, on the whole, taking too long. If so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  // bail out without attempting a collection.  The exceptions are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  // for explicitly requested GC's.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
  if (!policy->gc_time_limit_exceeded() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
      GCCause::is_user_requested_gc(gc_cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
      GCCause::is_serviceability_requested_gc(gc_cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
    IsGCActiveMark mark;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    if (ScavengeBeforeFullGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
      PSScavenge::invoke_no_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
    PSParallelCompact::invoke_no_policy(maximum_heap_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
bool ParallelCompactData::chunk_contains(size_t chunk_index, HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  size_t addr_chunk_index = addr_to_chunk_idx(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  return chunk_index == addr_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
bool ParallelCompactData::chunk_contains_block(size_t chunk_index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
                                               size_t block_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  size_t first_block_in_chunk = chunk_index * BlocksPerChunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
  size_t last_block_in_chunk = (chunk_index + 1) * BlocksPerChunk - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
  return (first_block_in_chunk <= block_index) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
         (block_index <= last_block_in_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
// This method contains no policy. You should probably
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
// be calling invoke() instead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  assert(ref_processor() != NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
386
7f121b1192f2 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 1
diff changeset
  1951
  if (GC_locker::check_active_before_gc()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  TimeStamp marking_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
  TimeStamp compaction_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
  TimeStamp collection_exit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
  GCCause::Cause gc_cause = heap->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
  PSPermGen* perm_gen = heap->perm_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
  PSAdaptiveSizePolicy* size_policy = heap->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1966
  if (ZapUnusedHeapArea) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1967
    // Save information needed to minimize mangling
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1968
    heap->record_gen_tops_before_GC();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1969
  }
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  1970
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  // Make sure data structures are sane, make the heap parsable, and do other
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
  // miscellaneous bookkeeping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  PreGCValues pre_gc_values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
  pre_compact(&pre_gc_values);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1978
  // Get the compaction manager reserved for the VM thread.
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1979
  ParCompactionManager* const vmthread_cm =
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1980
    ParCompactionManager::manager_array(gc_task_manager()->workers());
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  1981
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  // Place after pre_compact() where the number of invocations is incremented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
  AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
    HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
    const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
    // This is useful for debugging but don't change the output the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
    // the customer sees.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
    const char* gc_cause_str = "Full GC";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
    if (is_system_gc && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
      gc_cause_str = "Full GC (System)";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
    TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
    TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
    TraceMemoryManagerStats tms(true /* Full GC */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
    if (TraceGen1Time) accumulated_time()->start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
    // Let the size policy know we're starting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
    size_policy->major_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
    // When collecting the permanent generation methodOops may be moving,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
    // so we either have to flush all bcp data or convert it into bci.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
    CodeCache::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
    Threads::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
    COMPILER2_PRESENT(DerivedPointerTable::clear());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
    ref_processor()->enable_discovery();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
    bool marked_for_unloading = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
    marking_start.update();
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2021
    marking_phase(vmthread_cm, maximum_heap_compaction);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
    if (TraceParallelOldGCMarkingPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
      gclog_or_tty->print_cr("marking_phase: cas_tries %d  cas_retries %d "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
        "cas_by_another %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
        mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
        mark_bitmap()->cas_by_another());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
    if (VerifyParallelOldWithMarkSweep &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
        (PSParallelCompact::total_invocations() %
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
           VerifyParallelOldWithMarkSweepInterval) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
      gclog_or_tty->print_cr("Verify marking with mark_sweep_phase1()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
      if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
        gclog_or_tty->print_cr("mark_sweep_phase1:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
      // Clear the discovered lists so that discovered objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
      // don't look like they have been discovered twice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
      ref_processor()->clear_discovered_references();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
      PSMarkSweep::allocate_stacks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
      MemRegion mr = Universe::heap()->reserved_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
      PSMarkSweep::ref_processor()->enable_discovery();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
      PSMarkSweep::mark_sweep_phase1(maximum_heap_compaction);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
    bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc;
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2052
    summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
    if (VerifyParallelOldWithMarkSweep &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
        (PSParallelCompact::total_invocations() %
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
           VerifyParallelOldWithMarkSweepInterval) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
      if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
        gclog_or_tty->print_cr("mark_sweep_phase2:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
      PSMarkSweep::mark_sweep_phase2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
    COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
    COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
    // adjust_roots() updates Universe::_intArrayKlassObj which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
    // needed by the compaction for filling holes in the dense prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
    adjust_roots();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
    if (VerifyParallelOldWithMarkSweep &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
        (PSParallelCompact::total_invocations() %
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
           VerifyParallelOldWithMarkSweepInterval) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
      // Do a separate verify phase so that the verify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
      // code can use the the forwarding pointers to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
      // check the new pointer calculation.  The restore_marks()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
      // has to be done before the real compact.
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2080
      vmthread_cm->set_action(ParCompactionManager::VerifyUpdate);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2081
      compact_perm(vmthread_cm);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2082
      compact_serial(vmthread_cm);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2083
      vmthread_cm->set_action(ParCompactionManager::ResetObjects);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2084
      compact_perm(vmthread_cm);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2085
      compact_serial(vmthread_cm);
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2086
      vmthread_cm->set_action(ParCompactionManager::UpdateAndCopy);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
      // For debugging only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
      PSMarkSweep::restore_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
      PSMarkSweep::deallocate_stacks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
    compaction_start.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
    // Does the perm gen always have to be done serially because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
    // klasses are used in the update of an object?
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2097
    compact_perm(vmthread_cm);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
    if (UseParallelOldGCCompacting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
      compact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
    } else {
756
dc1ba65c5d1e 6676016: ParallelOldGC leaks memory
jcoomes
parents: 389
diff changeset
  2102
      compact_serial(vmthread_cm);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
    // Reset the mark bitmap, summary data, and do other bookkeeping.  Must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
    // done before resizing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
    post_compact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
    // Let the size policy know we're done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
    size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
      if (PrintAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
        gclog_or_tty->print("AdaptiveSizeStart: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
        gclog_or_tty->print_cr(" collection: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
                       heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
        if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
          gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
            " perm_gen_capacity: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
            perm_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
      // Don't check if the size_policy is ready here.  Let
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
      // the size_policy check that internally.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
      if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
          ((gc_cause != GCCause::_java_lang_system_gc) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
            UseAdaptiveSizePolicyWithSystemGC)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
        // Calculate optimal free space amounts
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
        assert(young_gen->max_size() >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
          young_gen->from_space()->capacity_in_bytes() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
          young_gen->to_space()->capacity_in_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
          "Sizes of space in young gen are out-of-bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
        size_t max_eden_size = young_gen->max_size() -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
          young_gen->from_space()->capacity_in_bytes() -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
          young_gen->to_space()->capacity_in_bytes();
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2139
        size_policy->compute_generation_free_space(
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2140
                              young_gen->used_in_bytes(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2141
                              young_gen->eden_space()->used_in_bytes(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2142
                              old_gen->used_in_bytes(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2143
                              perm_gen->used_in_bytes(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2144
                              young_gen->eden_space()->capacity_in_bytes(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2145
                              old_gen->max_gen_size(),
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2146
                              max_eden_size,
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2147
                              true /* full gc*/,
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2148
                              gc_cause);
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2149
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2150
        heap->resize_old_gen(
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2151
          size_policy->calculated_old_free_size_in_bytes());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
        // Don't resize the young generation at an major collection.  A
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
        // desired young generation size may have been calculated but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
        // resizing the young generation complicates the code because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
        // resizing of the old generation may have moved the boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
        // between the young generation and the old generation.  Let the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
        // young generation resizing happen at the minor collections.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
      if (PrintAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
        gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
                       heap->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
      PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
      counters->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
      counters->update_old_capacity(old_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
      counters->update_young_capacity(young_gen->capacity_in_bytes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
    heap->resize_all_tlabs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
    // We collected the perm gen, so we'll resize it here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    perm_gen->compute_new_size(pre_gc_values.perm_gen_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    if (TraceGen1Time) accumulated_time()->stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
    if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
        // No GC timestamp here.  This is after GC so it would be confusing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
        young_gen->print_used_change(pre_gc_values.young_gen_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
        old_gen->print_used_change(pre_gc_values.old_gen_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
        heap->print_heap_change(pre_gc_values.heap_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
        // Print perm gen last (print_heap_change() excludes the perm gen).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
        perm_gen->print_used_change(pre_gc_values.perm_gen_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
        heap->print_heap_change(pre_gc_values.heap_used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
    // Track memory usage and detect low memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    MemoryService::track_memory_usage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
    heap->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
      if (size_policy->print_gc_time_limit_would_be_exceeded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
        if (size_policy->gc_time_limit_exceeded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
          gclog_or_tty->print_cr("      GC time is exceeding GCTimeLimit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
            "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
          gclog_or_tty->print_cr("      GC time would exceed GCTimeLimit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
            "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
      size_policy->set_print_gc_time_limit_would_be_exceeded(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
  if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    gclog_or_tty->print(" VerifyAfterGC:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
    Universe::verify(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  // Re-verify object start arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
  if (VerifyObjectStartArray &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
      VerifyAfterGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
    old_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
    perm_gen->verify_object_start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2224
  if (ZapUnusedHeapArea) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2225
    old_gen->object_space()->check_mangled_unused_area_complete();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2226
    perm_gen->object_space()->check_mangled_unused_area_complete();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2227
  }
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 756
diff changeset
  2228
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
  NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
  collection_exit.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
  if (PrintHeapAtGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
    Universe::print_heap_after_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
  if (PrintGCTaskTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
    gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
                           INT64_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
                           marking_start.ticks(), compaction_start.ticks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
                           collection_exit.ticks());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
    gc_task_manager()->print_task_time_stamps();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
                                             PSYoungGen* young_gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
                                             PSOldGen* old_gen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
  MutableSpace* const eden_space = young_gen->eden_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  assert(!eden_space->is_empty(), "eden must be non-empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
  assert(young_gen->virtual_space()->alignment() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
         old_gen->virtual_space()->alignment(), "alignments do not match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
  if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
  // Both generations must be completely committed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  if (young_gen->virtual_space()->uncommitted_size() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  if (old_gen->virtual_space()->uncommitted_size() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
  // Figure out how much to take from eden.  Include the average amount promoted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
  // in the total; otherwise the next young gen GC will simply bail out to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
  // full GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
  const size_t alignment = old_gen->virtual_space()->alignment();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
  const size_t eden_used = eden_space->used_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
  const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
  const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  const size_t eden_capacity = eden_space->capacity_in_bytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  if (absorb_size >= eden_capacity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
    return false; // Must leave some space in eden.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
  if (new_young_size < young_gen->min_gen_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
    return false; // Respect young gen minimum size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  if (TraceAdaptiveGCBoundary && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
    gclog_or_tty->print(" absorbing " SIZE_FORMAT "K:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
                        "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
                        "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
                        "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
                        absorb_size / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
                        eden_capacity / K, (eden_capacity - absorb_size) / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
                        young_gen->from_space()->used_in_bytes() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
                        young_gen->to_space()->used_in_bytes() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
                        young_gen->capacity_in_bytes() / K, new_young_size / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
  // Fill the unused part of the old gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
  MutableSpace* const old_space = old_gen->object_space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
  MemRegion old_gen_unused(old_space->top(), old_space->end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
  if (!old_gen_unused.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
    SharedHeap::fill_region_with_object(old_gen_unused);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
  // Take the live data from eden and set both top and end in the old gen to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
  // eden top.  (Need to set end because reset_after_change() mangles the region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  // from end to virtual_space->high() in debug builds).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
  HeapWord* const new_top = eden_space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
  old_gen->virtual_space()->expand_into(young_gen->virtual_space(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
                                        absorb_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  young_gen->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  old_space->set_top(new_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  old_space->set_end(new_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  old_gen->reset_after_change();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
  // Update the object start array for the filler object and the data from eden.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
  ObjectStartArray* const start_array = old_gen->start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
  HeapWord* const start = old_gen_unused.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
  for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
    start_array->allocate_block(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
  // Could update the promoted average here, but it is not typically updated at
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
  // full GCs and the value to use is unclear.  Something like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
  // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  size_policy->set_bytes_absorbed_from_eden(absorb_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
GCTaskManager* const PSParallelCompact::gc_task_manager() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
  assert(ParallelScavengeHeap::gc_task_manager() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
    "shouldn't return NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
  return ParallelScavengeHeap::gc_task_manager();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
void PSParallelCompact::marking_phase(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
                                      bool maximum_heap_compaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
  // Recursively traverse all live objects and mark them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
  EventMark m("1 mark object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
  TraceTime tm("marking phase", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
  ParallelScavengeHeap* heap = gc_heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  uint parallel_gc_threads = heap->gc_task_manager()->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
  ParallelTaskTerminator terminator(parallel_gc_threads, qset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
  PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
    TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
    GCTaskQueue* q = GCTaskQueue::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
    // We scan the thread roots in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
    Threads::create_thread_roots_marking_tasks(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
    q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
    if (parallel_gc_threads > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      for (uint j = 0; j < parallel_gc_threads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
        q->enqueue(new StealMarkingTask(&terminator));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
    WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
    q->enqueue(fin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
    gc_task_manager()->add_list(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
    fin->wait_for();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
    // We have to release the barrier tasks!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
    WaitForBarrierGCTask::destroy(fin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
  // Process reference objects found during marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
    TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
    ReferencePolicy *soft_ref_policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
    if (maximum_heap_compaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
      soft_ref_policy = new AlwaysClearPolicy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
#ifdef COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
      soft_ref_policy = new LRUMaxHeapPolicy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
      soft_ref_policy = new LRUCurrentHeapPolicy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
#endif // COMPILER2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
    assert(soft_ref_policy != NULL, "No soft reference policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
    if (ref_processor()->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
      RefProcTaskExecutor task_executor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      ref_processor()->process_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
        soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
        &follow_stack_closure, &task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
      ref_processor()->process_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
        soft_ref_policy, is_alive_closure(), &mark_and_push_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
        &follow_stack_closure, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
  TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
  // Follow system dictionary roots and unload classes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
  bool purged_class = SystemDictionary::do_unloading(is_alive_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
  // Follow code cache roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
  CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
                          purged_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
  follow_stack(cm); // Flush marking stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
  // Update subklass/sibling/implementor links of live klasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  // revisit_klass_stack is used in follow_weak_klass_links().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
  follow_weak_klass_links(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
  // Visit symbol and interned string tables and delete unmarked oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  SymbolTable::unlink(is_alive_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
  StringTable::unlink(is_alive_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
  assert(cm->marking_stack()->size() == 0, "stack should be empty by now");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
  assert(cm->overflow_stack()->is_empty(), "stack should be empty by now");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
// This should be moved to the shared markSweep code!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
class PSAlwaysTrueClosure: public BoolObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
  void do_object(oop p) { ShouldNotReachHere(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  bool do_object_b(oop p) { return true; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
static PSAlwaysTrueClosure always_true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
void PSParallelCompact::adjust_roots() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  // Adjust the pointers to reflect the new locations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
  EventMark m("3 adjust roots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
  TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  // General strong roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
  Universe::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
  ReferenceProcessor::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
  JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
  Threads::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
  ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
  FlatProfiler::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
  Management::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
  JvmtiExport::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
  // SO_AllClasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
  SystemDictionary::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
  vmSymbols::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
  // Now adjust pointers in remaining weak roots.  (All of which should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
  // have been cleared if they pointed to non-surviving objects.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
  // Global (weak) JNI handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
  JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
  CodeCache::oops_do(adjust_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
  SymbolTable::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
  StringTable::oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
  ref_processor()->weak_oops_do(adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
  // Roots were visited so references into the young gen in roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
  // may have been scanned.  Process them also.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
  // Should the reference processor have a span that excludes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
  // young gen objects?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
  PSScavenge::reference_processor()->weak_oops_do(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
                                              adjust_root_pointer_closure());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
void PSParallelCompact::compact_perm(ParCompactionManager* cm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
  EventMark m("4 compact perm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
  TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
  // trace("4");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
  gc_heap()->perm_gen()->start_array()->reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
  move_and_update(cm, perm_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
void PSParallelCompact::enqueue_chunk_draining_tasks(GCTaskQueue* q,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
                                                     uint parallel_gc_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
  TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
  const unsigned int task_count = MAX2(parallel_gc_threads, 1U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
  for (unsigned int j = 0; j < task_count; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
    q->enqueue(new DrainStacksCompactionTask());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
  // Find all chunks that are available (can be filled immediately) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  // distribute them to the thread stacks.  The iteration is done in reverse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  // order (high to low) so the chunks will be removed in ascending order.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
  const ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
  size_t fillable_chunks = 0;   // A count for diagnostic purposes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
  unsigned int which = 0;       // The worker thread number.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
  for (unsigned int id = to_space_id; id > perm_space_id; --id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
    SpaceInfo* const space_info = _space_info + id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
    MutableSpace* const space = space_info->space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
    HeapWord* const new_top = space_info->new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
    const size_t beg_chunk = sd.addr_to_chunk_idx(space_info->dense_prefix());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
    const size_t end_chunk = sd.addr_to_chunk_idx(sd.chunk_align_up(new_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
    assert(end_chunk > 0, "perm gen cannot be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
    for (size_t cur = end_chunk - 1; cur >= beg_chunk; --cur) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
      if (sd.chunk(cur)->claim_unsafe()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
        ParCompactionManager* cm = ParCompactionManager::manager_array(which);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
        cm->save_for_processing(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
        if (TraceParallelOldGCCompactionPhase && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
          const size_t count_mod_8 = fillable_chunks & 7;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
          if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
972
b86fd2f84aaf 6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents: 971
diff changeset
  2516
          gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
          if (count_mod_8 == 7) gclog_or_tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
        NOT_PRODUCT(++fillable_chunks;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
        // Assign chunks to threads in round-robin fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
        if (++which == task_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
          which = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
  if (TraceParallelOldGCCompactionPhase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
    if (Verbose && (fillable_chunks & 7) != 0) gclog_or_tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
    gclog_or_tty->print_cr("%u initially fillable chunks", fillable_chunks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
#define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 4
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
                                                    uint parallel_gc_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
  TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
  // Iterate over all the spaces adding tasks for updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  // chunks in the dense prefix.  Assume that 1 gc thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
  // will work on opening the gaps and the remaining gc threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
  // will work on the dense prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
  SpaceId space_id = old_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  while (space_id != last_space_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
    HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
    const MutableSpace* const space = _space_info[space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
    if (dense_prefix_end == space->bottom()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
      // There is no dense prefix for this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
      space_id = next_compaction_space_id(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    // The dense prefix is before this chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    size_t chunk_index_end_dense_prefix =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
        sd.addr_to_chunk_idx(dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
    ChunkData* const dense_prefix_cp = sd.chunk(chunk_index_end_dense_prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
    assert(dense_prefix_end == space->end() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
           dense_prefix_cp->available() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
           dense_prefix_cp->claimed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
           "The chunk after the dense prefix should always be ready to fill");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
    size_t chunk_index_start = sd.addr_to_chunk_idx(space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
    // Is there dense prefix work?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
    size_t total_dense_prefix_chunks =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
      chunk_index_end_dense_prefix - chunk_index_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
    // How many chunks of the dense prefix should be given to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
    // each thread?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
    if (total_dense_prefix_chunks > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
      uint tasks_for_dense_prefix = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
      if (UseParallelDensePrefixUpdate) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
        if (total_dense_prefix_chunks <=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
            (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
          // Don't over partition.  This assumes that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
          // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
          // so there are not many chunks to process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
          tasks_for_dense_prefix = parallel_gc_threads;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
          // Over partition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
          tasks_for_dense_prefix = parallel_gc_threads *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
            PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
      size_t chunks_per_thread = total_dense_prefix_chunks /
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
        tasks_for_dense_prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
      // Give each thread at least 1 chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
      if (chunks_per_thread == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
        chunks_per_thread = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
      for (uint k = 0; k < tasks_for_dense_prefix; k++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
        if (chunk_index_start >= chunk_index_end_dense_prefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
        // chunk_index_end is not processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
        size_t chunk_index_end = MIN2(chunk_index_start + chunks_per_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
                                      chunk_index_end_dense_prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
        q->enqueue(new UpdateDensePrefixTask(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
                                 space_id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
                                 chunk_index_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
                                 chunk_index_end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
        chunk_index_start = chunk_index_end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
    // This gets any part of the dense prefix that did not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
    // fit evenly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
    if (chunk_index_start < chunk_index_end_dense_prefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
      q->enqueue(new UpdateDensePrefixTask(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
                                 space_id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
                                 chunk_index_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
                                 chunk_index_end_dense_prefix));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
    space_id = next_compaction_space_id(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
  }  // End tasks for dense prefix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
void PSParallelCompact::enqueue_chunk_stealing_tasks(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
                                     GCTaskQueue* q,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
                                     ParallelTaskTerminator* terminator_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
                                     uint parallel_gc_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
  TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
  // Once a thread has drained it's stack, it should try to steal chunks from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
  // other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
  if (parallel_gc_threads > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
    for (uint j = 0; j < parallel_gc_threads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
      q->enqueue(new StealChunkCompactionTask(terminator_ptr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
void PSParallelCompact::compact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
  EventMark m("5 compact");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
  // trace("5");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
  old_gen->start_array()->reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  uint parallel_gc_threads = heap->gc_task_manager()->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
  TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  ParallelTaskTerminator terminator(parallel_gc_threads, qset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
  GCTaskQueue* q = GCTaskQueue::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
  enqueue_chunk_draining_tasks(q, parallel_gc_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
  enqueue_dense_prefix_tasks(q, parallel_gc_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
  enqueue_chunk_stealing_tasks(q, &terminator, parallel_gc_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
    q->enqueue(fin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
    gc_task_manager()->add_list(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
    fin->wait_for();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
    // We have to release the barrier tasks!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
    WaitForBarrierGCTask::destroy(fin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
    // Verify that all chunks have been processed before the deferred updates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
    // Note that perm_space_id is skipped; this type of verification is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
    // valid until the perm gen is compacted by chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
    for (unsigned int id = old_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
      verify_complete(SpaceId(id));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
    // Update the deferred objects, if any.  Any compaction manager can be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
    TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
    ParCompactionManager* cm = ParCompactionManager::manager_array(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
    for (unsigned int id = old_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
      update_deferred_objects(cm, SpaceId(id));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
void PSParallelCompact::verify_complete(SpaceId space_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  // All Chunks between space bottom() to new_top() should be marked as filled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
  // and all Chunks between new_top() and top() should be available (i.e.,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
  // should have been emptied).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
  SpaceInfo si = _space_info[space_id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  HeapWord* new_top_addr = sd.chunk_align_up(si.new_top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  HeapWord* old_top_addr = sd.chunk_align_up(si.space()->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
  const size_t beg_chunk = sd.addr_to_chunk_idx(si.space()->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  const size_t new_top_chunk = sd.addr_to_chunk_idx(new_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  const size_t old_top_chunk = sd.addr_to_chunk_idx(old_top_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
  bool issued_a_warning = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  size_t cur_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  for (cur_chunk = beg_chunk; cur_chunk < new_top_chunk; ++cur_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
    const ChunkData* const c = sd.chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
    if (!c->completed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
      warning("chunk " SIZE_FORMAT " not filled:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
              "destination_count=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
              cur_chunk, c->destination_count());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
      issued_a_warning = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  for (cur_chunk = new_top_chunk; cur_chunk < old_top_chunk; ++cur_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
    const ChunkData* const c = sd.chunk(cur_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
    if (!c->available()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
      warning("chunk " SIZE_FORMAT " not empty:   "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
              "destination_count=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
              cur_chunk, c->destination_count());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
      issued_a_warning = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
  if (issued_a_warning) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
    print_chunk_ranges();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
void PSParallelCompact::compact_serial(ParCompactionManager* cm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  EventMark m("5 compact serial");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
  TraceTime tm("compact serial", print_phases(), true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
  PSYoungGen* young_gen = heap->young_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
  old_gen->start_array()->reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
  old_gen->move_and_update(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  young_gen->move_and_update(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
void PSParallelCompact::follow_stack(ParCompactionManager* cm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
  while(!cm->overflow_stack()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
    oop obj = cm->overflow_stack()->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
    obj->follow_contents(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  oop obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
  // obj is a reference!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
  while (cm->marking_stack()->pop_local(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
    // It would be nice to assert about the type of objects we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
    // pop, but they can come from anywhere, unfortunately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
    obj->follow_contents(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
PSParallelCompact::follow_weak_klass_links(ParCompactionManager* serial_cm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
  // All klasses on the revisit stack are marked at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
  // Update and follow all subklass, sibling and implementor links.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
  for (uint i = 0; i < ParallelGCThreads+1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
    ParCompactionManager* cm = ParCompactionManager::manager_array(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
    KeepAliveClosure keep_alive_closure(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
    for (int i = 0; i < cm->revisit_klass_stack()->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
      cm->revisit_klass_stack()->at(i)->follow_weak_klass_links(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
        is_alive_closure(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
        &keep_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
    follow_stack(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
  cm->revisit_klass_stack()->push(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
#ifdef VALIDATE_MARK_SWEEP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
  2785
void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
  if (!ValidateMarkSweep)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  if (!isroot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
    if (_pointer_tracking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
      guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
      _adjusted_pointers->remove(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
    ptrdiff_t index = _root_refs_stack->find(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
    if (index != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
      int l = _root_refs_stack->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
      if (l > 0 && l - 1 != index) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
  2799
        void* last = _root_refs_stack->pop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
        assert(last != p, "should be different");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
        _root_refs_stack->at_put(index, last);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
        _root_refs_stack->remove(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
  2810
void PSParallelCompact::check_adjust_pointer(void* p) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  _adjusted_pointers->push(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
class AdjusterTracker: public OopClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
  AdjusterTracker() {};
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
  2818
  void do_oop(oop* o)         { PSParallelCompact::check_adjust_pointer(o); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 252
diff changeset
  2819
  void do_oop(narrowOop* o)   { PSParallelCompact::check_adjust_pointer(o); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
void PSParallelCompact::track_interior_pointers(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
    _adjusted_pointers->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
    _pointer_tracking = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
    AdjusterTracker checker;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
    obj->oop_iterate(&checker);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
void PSParallelCompact::check_interior_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
    _pointer_tracking = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
    guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
void PSParallelCompact::reset_live_oop_tracking(bool at_perm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
    guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
    _live_oops_index = at_perm ? _live_oops_index_at_perm : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
void PSParallelCompact::register_live_oop(oop p, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
    _live_oops->push(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
    _live_oops_size->push(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
    _live_oops_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
void PSParallelCompact::validate_live_oop(oop p, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
    oop obj = _live_oops->at((int)_live_oops_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
    guarantee(obj == p, "should be the same object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
    guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
    _live_oops_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
                                  HeapWord* compaction_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
  assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
         "should be moved to forwarded location");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  if (ValidateMarkSweep) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
    PSParallelCompact::validate_live_oop(oop(q), size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
    _live_oops_moved_to->push(oop(compaction_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  if (RecordMarkSweepCompaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
    _cur_gc_live_oops->push(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
    _cur_gc_live_oops_moved_to->push(compaction_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
    _cur_gc_live_oops_size->push(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
void PSParallelCompact::compaction_complete() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
  if (RecordMarkSweepCompaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
    GrowableArray<HeapWord*>* _tmp_live_oops          = _cur_gc_live_oops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
    GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
    GrowableArray<size_t>   * _tmp_live_oops_size     = _cur_gc_live_oops_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
    _cur_gc_live_oops           = _last_gc_live_oops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
    _cur_gc_live_oops_moved_to  = _last_gc_live_oops_moved_to;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    _cur_gc_live_oops_size      = _last_gc_live_oops_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
    _last_gc_live_oops          = _tmp_live_oops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
    _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
    _last_gc_live_oops_size     = _tmp_live_oops_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
  if (!RecordMarkSweepCompaction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
    tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
  if (_last_gc_live_oops == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
    tty->print_cr("No compaction information gathered yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
  for (int i = 0; i < _last_gc_live_oops->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
    HeapWord* old_oop = _last_gc_live_oops->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
    size_t    sz      = _last_gc_live_oops_size->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
    if (old_oop <= q && q < (old_oop + sz)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
      HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
      size_t offset = (q - old_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
      tty->print_cr("Address " PTR_FORMAT, q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
      tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
      tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
#endif //VALIDATE_MARK_SWEEP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
// Update interior oops in the ranges of chunks [beg_chunk, end_chunk).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
                                                       SpaceId space_id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
                                                       size_t beg_chunk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
                                                       size_t end_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
  ParMarkBitMap* const mbm = mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
  HeapWord* beg_addr = sd.chunk_to_addr(beg_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
  HeapWord* const end_addr = sd.chunk_to_addr(end_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
  assert(beg_chunk <= end_chunk, "bad chunk range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  assert(end_addr <= dense_prefix(space_id), "not in the dense prefix");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
#ifdef  ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  // Claim the chunks to avoid triggering an assert when they are marked as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  // filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  for (size_t claim_chunk = beg_chunk; claim_chunk < end_chunk; ++claim_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
    assert(sd.chunk(claim_chunk)->claim_unsafe(), "claim() failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
#endif  // #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
  if (beg_addr != space(space_id)->bottom()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
    // Find the first live object or block of dead space that *starts* in this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
    // range of chunks.  If a partial object crosses onto the chunk, skip it; it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
    // will be marked for 'deferred update' when the object head is processed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
    // If dead space crosses onto the chunk, it is also skipped; it will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
    // filled when the prior chunk is processed.  If neither of those apply, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
    // first word in the chunk is the start of a live object or dead space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
    assert(beg_addr > space(space_id)->bottom(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
    const ChunkData* const cp = sd.chunk(beg_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
    if (cp->partial_obj_size() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
      beg_addr = sd.partial_obj_end(beg_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
    } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
      beg_addr = mbm->find_obj_beg(beg_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
  if (beg_addr < end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
    // A live object or block of dead space starts in this range of Chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
     HeapWord* const dense_prefix_end = dense_prefix(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
    // Create closures and iterate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
    UpdateOnlyClosure update_closure(mbm, cm, space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
    FillClosure fill_closure(cm, space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
    ParMarkBitMap::IterationStatus status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
    status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
                          dense_prefix_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
    if (status == ParMarkBitMap::incomplete) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
      update_closure.do_addr(update_closure.source());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  // Mark the chunks as filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
  ChunkData* const beg_cp = sd.chunk(beg_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  ChunkData* const end_cp = sd.chunk(end_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
  for (ChunkData* cp = beg_cp; cp < end_cp; ++cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
    cp->set_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
// Return the SpaceId for the space containing addr.  If addr is not in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
// heap, last_space_id is returned.  In debug mode it expects the address to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
// in the heap and asserts such.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  for (unsigned int id = perm_space_id; id < last_space_id; ++id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
    if (_space_info[id].space()->contains(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
      return SpaceId(id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  assert(false, "no space contains the addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
  return last_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
                                                SpaceId id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  assert(id < last_space_id, "bad space id");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
  const SpaceInfo* const space_info = _space_info + id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
  ObjectStartArray* const start_array = space_info->start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
  const MutableSpace* const space = space_info->space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
  HeapWord* const beg_addr = space_info->dense_prefix();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  HeapWord* const end_addr = sd.chunk_align_up(space_info->new_top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
  const ChunkData* const beg_chunk = sd.addr_to_chunk_ptr(beg_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
  const ChunkData* const end_chunk = sd.addr_to_chunk_ptr(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
  const ChunkData* cur_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
  for (cur_chunk = beg_chunk; cur_chunk < end_chunk; ++cur_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
    HeapWord* const addr = cur_chunk->deferred_obj_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
    if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
      if (start_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
        start_array->allocate_block(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
      oop(addr)->update_contents(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
      assert(oop(addr)->is_oop_or_null(), "should be an oop now");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
// Skip over count live words starting from beg, and return the address of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
// next live word.  Unless marked, the word corresponding to beg is assumed to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
// be dead.  Callers must either ensure beg does not correspond to the middle of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
// an object, or account for those live words in some other way.  Callers must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
// also ensure that there are enough live words in the range [beg, end) to skip.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
  assert(count > 0, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
  ParMarkBitMap* m = mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  idx_t bits_to_skip = m->words_to_bits(count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
  idx_t cur_beg = m->addr_to_bit(beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  const idx_t search_end = BitMap::word_align_up(m->addr_to_bit(end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
    cur_beg = m->find_obj_beg(cur_beg, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
    idx_t cur_end = m->find_obj_end(cur_beg, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
    const size_t obj_bits = cur_end - cur_beg + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
    if (obj_bits > bits_to_skip) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
      return m->bit_to_addr(cur_beg + bits_to_skip);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
    bits_to_skip -= obj_bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
    cur_beg = cur_end + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
  } while (bits_to_skip > 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
  // Skipping the desired number of words landed just past the end of an object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
  // Find the start of the next object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
  cur_beg = m->find_obj_beg(cur_beg, search_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
  assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
  return m->bit_to_addr(cur_beg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
PSParallelCompact::first_src_addr(HeapWord* const dest_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
                                 size_t src_chunk_idx)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
  ParMarkBitMap* const bitmap = mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
  const ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
  const size_t ChunkSize = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
  assert(sd.is_chunk_aligned(dest_addr), "not aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
  const ChunkData* const src_chunk_ptr = sd.chunk(src_chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
  const size_t partial_obj_size = src_chunk_ptr->partial_obj_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
  HeapWord* const src_chunk_destination = src_chunk_ptr->destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
  assert(dest_addr >= src_chunk_destination, "wrong src chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
  assert(src_chunk_ptr->data_size() > 0, "src chunk cannot be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
  HeapWord* const src_chunk_beg = sd.chunk_to_addr(src_chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
  HeapWord* const src_chunk_end = src_chunk_beg + ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
  HeapWord* addr = src_chunk_beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
  if (dest_addr == src_chunk_destination) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
    // Return the first live word in the source chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
    if (partial_obj_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
      addr = bitmap->find_obj_beg(addr, src_chunk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
      assert(addr < src_chunk_end, "no objects start in src chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
    return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
  // Must skip some live data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
  size_t words_to_skip = dest_addr - src_chunk_destination;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
  assert(src_chunk_ptr->data_size() > words_to_skip, "wrong src chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
  if (partial_obj_size >= words_to_skip) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
    // All the live words to skip are part of the partial object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
    addr += words_to_skip;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
    if (partial_obj_size == words_to_skip) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
      // Find the first live word past the partial object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
      addr = bitmap->find_obj_beg(addr, src_chunk_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
      assert(addr < src_chunk_end, "wrong src chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
    return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  // Skip over the partial object (if any).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
  if (partial_obj_size != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
    words_to_skip -= partial_obj_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
    addr += partial_obj_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  // Skip over live words due to objects that start in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
  addr = skip_live_words(addr, src_chunk_end, words_to_skip);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
  assert(addr < src_chunk_end, "wrong src chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
  return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
                                                     size_t beg_chunk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
                                                     HeapWord* end_addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
  ChunkData* const beg = sd.chunk(beg_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
  HeapWord* const end_addr_aligned_up = sd.chunk_align_up(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
  ChunkData* const end = sd.addr_to_chunk_ptr(end_addr_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
  size_t cur_idx = beg_chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
  for (ChunkData* cur = beg; cur < end; ++cur, ++cur_idx) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
    assert(cur->data_size() > 0, "chunk must have live data");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    cur->decrement_destination_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
    if (cur_idx <= cur->source_chunk() && cur->available() && cur->claim()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
      cm->save_for_processing(cur_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
size_t PSParallelCompact::next_src_chunk(MoveAndUpdateClosure& closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
                                         SpaceId& src_space_id,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
                                         HeapWord*& src_space_top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
                                         HeapWord* end_addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
  typedef ParallelCompactData::ChunkData ChunkData;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
  const size_t chunk_size = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
  size_t src_chunk_idx = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
  // Skip empty chunks (if any) up to the top of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
  HeapWord* const src_aligned_up = sd.chunk_align_up(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3154
  ChunkData* src_chunk_ptr = sd.addr_to_chunk_ptr(src_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
  HeapWord* const top_aligned_up = sd.chunk_align_up(src_space_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
  const ChunkData* const top_chunk_ptr = sd.addr_to_chunk_ptr(top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
  while (src_chunk_ptr < top_chunk_ptr && src_chunk_ptr->data_size() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
    ++src_chunk_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
  if (src_chunk_ptr < top_chunk_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
    // The next source chunk is in the current space.  Update src_chunk_idx and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
    // the source address to match src_chunk_ptr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
    src_chunk_idx = sd.chunk(src_chunk_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
    HeapWord* const src_chunk_addr = sd.chunk_to_addr(src_chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
    if (src_chunk_addr > closure.source()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
      closure.set_source(src_chunk_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
    return src_chunk_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
  // Switch to a new source space and find the first non-empty chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  unsigned int space_id = src_space_id + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
  assert(space_id < last_space_id, "not enough spaces");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
  HeapWord* const destination = closure.destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
    MutableSpace* space = _space_info[space_id].space();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
    HeapWord* const bottom = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
    const ChunkData* const bottom_cp = sd.addr_to_chunk_ptr(bottom);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
    // Iterate over the spaces that do not compact into themselves.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
    if (bottom_cp->destination() != bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
      HeapWord* const top_aligned_up = sd.chunk_align_up(space->top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
      const ChunkData* const top_cp = sd.addr_to_chunk_ptr(top_aligned_up);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
      for (const ChunkData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
        if (src_cp->live_obj_size() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
          // Found it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
          assert(src_cp->destination() == destination,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
                 "first live obj in the space must match the destination");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
          assert(src_cp->partial_obj_size() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
                 "a space cannot begin with a partial obj");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
          src_space_id = SpaceId(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
          src_space_top = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
          const size_t src_chunk_idx = sd.chunk(src_cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
          closure.set_source(sd.chunk_to_addr(src_chunk_idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
          return src_chunk_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
          assert(src_cp->data_size() == 0, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
  } while (++space_id < last_space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
  assert(false, "no source chunk was found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
void PSParallelCompact::fill_chunk(ParCompactionManager* cm, size_t chunk_idx)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
  typedef ParMarkBitMap::IterationStatus IterationStatus;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
  const size_t ChunkSize = ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
  ParMarkBitMap* const bitmap = mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
  ParallelCompactData& sd = summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
  ChunkData* const chunk_ptr = sd.chunk(chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
  // Get the items needed to construct the closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
  HeapWord* dest_addr = sd.chunk_to_addr(chunk_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
  SpaceId dest_space_id = space_id(dest_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
  ObjectStartArray* start_array = _space_info[dest_space_id].start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
  HeapWord* new_top = _space_info[dest_space_id].new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
  assert(dest_addr < new_top, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
  const size_t words = MIN2(pointer_delta(new_top, dest_addr), ChunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
  // Get the source chunk and related info.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  size_t src_chunk_idx = chunk_ptr->source_chunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
  SpaceId src_space_id = space_id(sd.chunk_to_addr(src_chunk_idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
  HeapWord* src_space_top = _space_info[src_space_id].space()->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
  MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
  closure.set_source(first_src_addr(dest_addr, src_chunk_idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
  // Adjust src_chunk_idx to prepare for decrementing destination counts (the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
  // destination count is not decremented when a chunk is copied to itself).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
  if (src_chunk_idx == chunk_idx) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
    src_chunk_idx += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
  if (bitmap->is_unmarked(closure.source())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
    // The first source word is in the middle of an object; copy the remainder
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
    // of the object or as much as will fit.  The fact that pointer updates were
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
    // deferred will be noted when the object header is processed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
    HeapWord* const old_src_addr = closure.source();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
    closure.copy_partial_obj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
    if (closure.is_full()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
      decrement_destination_counts(cm, src_chunk_idx, closure.source());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
      chunk_ptr->set_deferred_obj_addr(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
      chunk_ptr->set_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
    HeapWord* const end_addr = sd.chunk_align_down(closure.source());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
    if (sd.chunk_align_down(old_src_addr) != end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
      // The partial object was copied from more than one source chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
      decrement_destination_counts(cm, src_chunk_idx, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
      // Move to the next source chunk, possibly switching spaces as well.  All
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
      // args except end_addr may be modified.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
      src_chunk_idx = next_src_chunk(closure, src_space_id, src_space_top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
                                     end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
    HeapWord* const cur_addr = closure.source();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
    HeapWord* const end_addr = MIN2(sd.chunk_align_up(cur_addr + 1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
                                    src_space_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
    IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
    if (status == ParMarkBitMap::incomplete) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
      // The last obj that starts in the source chunk does not end in the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
      assert(closure.source() < end_addr, "sanity")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
      HeapWord* const obj_beg = closure.source();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
      HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
                                       src_space_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
      HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
      if (obj_end < range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
        // The end was found; the entire object will fit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
        status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
        assert(status != ParMarkBitMap::would_overflow, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
        // The end was not found; the object will not fit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
        assert(range_end < src_space_top, "obj cannot cross space boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
        status = ParMarkBitMap::would_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
    if (status == ParMarkBitMap::would_overflow) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
      // The last object did not fit.  Note that interior oop updates were
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
      // deferred, then copy enough of the object to fill the chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
      chunk_ptr->set_deferred_obj_addr(closure.destination());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
      status = closure.copy_until_full(); // copies from closure.source()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
      decrement_destination_counts(cm, src_chunk_idx, closure.source());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
      chunk_ptr->set_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
    if (status == ParMarkBitMap::full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
      decrement_destination_counts(cm, src_chunk_idx, closure.source());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
      chunk_ptr->set_deferred_obj_addr(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
      chunk_ptr->set_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
    decrement_destination_counts(cm, src_chunk_idx, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
    // Move to the next source chunk, possibly switching spaces as well.  All
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
    // args except end_addr may be modified.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
    src_chunk_idx = next_src_chunk(closure, src_space_id, src_space_top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
                                   end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
  } while (true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  const MutableSpace* sp = space(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  if (sp->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  ParMarkBitMap* const bitmap = mark_bitmap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  HeapWord* const dp_addr = dense_prefix(space_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
  HeapWord* beg_addr = sp->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  HeapWord* end_addr = sp->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
  assert(beg_addr <= dp_addr && dp_addr <= end_addr, "bad dense prefix");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
  if (cm->should_verify_only()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
    VerifyUpdateClosure verify_update(cm, sp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
    bitmap->iterate(&verify_update, beg_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
  if (cm->should_reset_only()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
    ResetObjectsClosure reset_objects(cm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
    bitmap->iterate(&reset_objects, beg_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
  const size_t beg_chunk = sd.addr_to_chunk_idx(beg_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
  const size_t dp_chunk = sd.addr_to_chunk_idx(dp_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
  if (beg_chunk < dp_chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
    update_and_deadwood_in_dense_prefix(cm, space_id, beg_chunk, dp_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  // The destination of the first live object that starts in the chunk is one
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
  // past the end of the partial object entering the chunk (if any).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
  HeapWord* const dest_addr = sd.partial_obj_end(dp_chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
  HeapWord* const new_top = _space_info[space_id].new_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
  assert(new_top >= dest_addr, "bad new_top value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
  const size_t words = pointer_delta(new_top, dest_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
  if (words > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    ObjectStartArray* start_array = _space_info[space_id].start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
    MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
    ParMarkBitMap::IterationStatus status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
    status = bitmap->iterate(&closure, dest_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
    assert(status == ParMarkBitMap::full, "iteration not complete");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
    assert(bitmap->find_obj_beg(closure.source(), end_addr) == end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
           "live objects skipped because closure is full");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
jlong PSParallelCompact::millis_since_last_gc() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  jlong ret_val = os::javaTimeMillis() - _time_of_last_gc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
  // XXX See note in genCollectedHeap::millis_since_last_gc().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
  if (ret_val < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    NOT_PRODUCT(warning("time warp: %d", ret_val);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
  return ret_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
void PSParallelCompact::reset_millis_since_last_gc() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
  _time_of_last_gc = os::javaTimeMillis();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  if (source() != destination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
    assert(source() > destination(), "must copy to the left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
    Copy::aligned_conjoint_words(source(), destination(), words_remaining());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
  update_state(words_remaining());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
  assert(is_full(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
  return ParMarkBitMap::full;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
void MoveAndUpdateClosure::copy_partial_obj()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
  size_t words = words_remaining();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
  if (end_addr < range_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
    words = bitmap()->obj_size(source(), end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  // This test is necessary; if omitted, the pointer updates to a partial object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
  // that crosses the dense prefix boundary could be overwritten.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
  if (source() != destination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
    assert(source() > destination(), "must copy to the left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
    Copy::aligned_conjoint_words(source(), destination(), words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
  update_state(words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
ParMarkBitMapClosure::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  assert(destination() != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
  assert(bitmap()->obj_size(addr) == words, "bad size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
  _source = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
  assert(PSParallelCompact::summary_data().calc_new_pointer(source()) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
         destination(), "wrong destination");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  if (words > words_remaining()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
    return ParMarkBitMap::would_overflow;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
  // The start_array must be updated even if the object is not moving.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
  if (_start_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
    _start_array->allocate_block(destination());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
  if (destination() != source()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
    assert(destination() < source(), "must copy to the left");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
    Copy::aligned_conjoint_words(source(), destination(), words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  oop moved_oop = (oop) destination();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
  moved_oop->update_contents(compaction_manager());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
  assert(moved_oop->is_oop_or_null(), "Object should be whole at this point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
  update_state(words);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
                                     ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
                                     PSParallelCompact::SpaceId space_id) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
  ParMarkBitMapClosure(mbm, cm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  _space_id(space_id),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  _start_array(PSParallelCompact::start_array(space_id))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
// Updates the references in the object to their new values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
ParMarkBitMapClosure::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
  do_addr(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
  return ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
BitBlockUpdateClosure::BitBlockUpdateClosure(ParMarkBitMap* mbm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
                        ParCompactionManager* cm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
                        size_t chunk_index) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
                        ParMarkBitMapClosure(mbm, cm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
                        _live_data_left(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
                        _cur_block(0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
  _chunk_start =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
    PSParallelCompact::summary_data().chunk_to_addr(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
  _chunk_end =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
    PSParallelCompact::summary_data().chunk_to_addr(chunk_index) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
                 ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
  _chunk_index = chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
  _cur_block =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
    PSParallelCompact::summary_data().addr_to_block_idx(_chunk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
bool BitBlockUpdateClosure::chunk_contains_cur_block() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
  return ParallelCompactData::chunk_contains_block(_chunk_index, _cur_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
void BitBlockUpdateClosure::reset_chunk(size_t chunk_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(7);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
  _chunk_index = chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  _live_data_left = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
  _chunk_start = sd.chunk_to_addr(chunk_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
  _chunk_end = sd.chunk_to_addr(chunk_index) + ParallelCompactData::ChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
  // The first block in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
  size_t first_block =  sd.addr_to_block_idx(_chunk_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
  size_t partial_live_size = sd.chunk(chunk_index)->partial_obj_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
  // Set the offset to 0. By definition it should have that value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
  // but it may have been written while processing an earlier chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
  if (partial_live_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
    // No live object extends onto the chunk.  The first bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
    // in the bit map for the first chunk must be a start bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
    // Although there may not be any marked bits, it is safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
    // to set it as a start bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
    sd.block(first_block)->set_start_bit_offset(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
    sd.block(first_block)->set_first_is_start_bit(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
  } else if (sd.partial_obj_ends_in_block(first_block)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
    sd.block(first_block)->set_end_bit_offset(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
    sd.block(first_block)->set_first_is_start_bit(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
    // The partial object extends beyond the first block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
    // There is no object starting in the first block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
    // so the offset and bit parity are not needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
    // Set the the bit parity to start bit so assertions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
    // work when not bit is found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
    sd.block(first_block)->set_end_bit_offset(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
    sd.block(first_block)->set_first_is_start_bit(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
  _cur_block = first_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  if (sd.block(first_block)->first_is_start_bit()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
    assert(!sd.partial_obj_ends_in_block(first_block),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
      "Partial object cannot end in first block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
    if (partial_live_size == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
    gclog_or_tty->print_cr("first_block " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
      " _offset " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
      " _first_is_start_bit %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
      first_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
      sd.block(first_block)->raw_offset(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
      sd.block(first_block)->first_is_start_bit());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(17);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
// This method is called when a object has been found (both beginning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
// and end of the object) in the range of iteration.  This method is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
// calculating the words of live data to the left of a block.  That live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
// data includes any object starting to the left of the block (i.e.,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
// the live-data-to-the-left of block AAA will include the full size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
// of any object entering AAA).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
ParMarkBitMapClosure::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
BitBlockUpdateClosure::do_addr(HeapWord* addr, size_t words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
  // add the size to the block data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
  HeapWord* obj = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
  ParallelCompactData& sd = PSParallelCompact::summary_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
  assert(bitmap()->obj_size(obj) == words, "bad size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
  assert(_chunk_start <= obj, "object is not in chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
  assert(obj + words <= _chunk_end, "object is not in chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
  // Update the live data to the left
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
  size_t prev_live_data_left = _live_data_left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
  _live_data_left = _live_data_left + words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
  // Is this object in the current block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
  size_t block_of_obj = sd.addr_to_block_idx(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
  size_t block_of_obj_last = sd.addr_to_block_idx(obj + words - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
  HeapWord* block_of_obj_last_addr = sd.block_to_addr(block_of_obj_last);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
  if (_cur_block < block_of_obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
    // No object crossed the block boundary and this object was found
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
    // on the other side of the block boundary.  Update the offset for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
    // the new block with the data size that does not include this object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
    // The first bit in block_of_obj is a start bit except in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
    // case where the partial object for the chunk extends into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
    // this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
    if (sd.partial_obj_ends_in_block(block_of_obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
      sd.block(block_of_obj)->set_end_bit_offset(prev_live_data_left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
      sd.block(block_of_obj)->set_start_bit_offset(prev_live_data_left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
    // Does this object pass beyond the its block?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
    if (block_of_obj < block_of_obj_last) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
      // Object crosses block boundary.  Two blocks need to be udpated:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
      //        the current block where the object started
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
      //        the block where the object ends
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
      // The offset for blocks with no objects starting in them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
      // (e.g., blocks between _cur_block and  block_of_obj_last)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
      // should not be needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
      // Note that block_of_obj_last may be in another chunk.  If so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
      // it should be overwritten later.  This is a problem (writting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
      // into a block in a later chunk) for parallel execution.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
      assert(obj < block_of_obj_last_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
        "Object should start in previous block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
      // obj is crossing into block_of_obj_last so the first bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
      // is and end bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
      sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
      _cur_block = block_of_obj_last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
      // _first_is_start_bit has already been set correctly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
      // in the if-then-else above so don't reset it here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
      _cur_block = block_of_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
    // The current block only changes if the object extends beyound
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
    // the block it starts in.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
    // The object starts in the current block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
    // Does this object pass beyond the end of it?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
    if (block_of_obj < block_of_obj_last) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
      // Object crosses block boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
      // See note above on possible blocks between block_of_obj and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
      // block_of_obj_last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
      assert(obj < block_of_obj_last_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
        "Object should start in previous block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
      sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
      _cur_block = block_of_obj_last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
  // Return incomplete if there are more blocks to be done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
  if (chunk_contains_cur_block()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
    return ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  return ParMarkBitMap::complete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
// Verify the new location using the forwarding pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
// from MarkSweep::mark_sweep_phase2().  Set the mark_word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
// to the initial value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
ParMarkBitMapClosure::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  // The second arg (words) is not used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
  oop obj = (oop) addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
  HeapWord* forwarding_ptr = (HeapWord*) obj->mark()->decode_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
  HeapWord* new_pointer = summary_data().calc_new_pointer(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
  if (forwarding_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
    // The object is dead or not moving.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
    assert(bitmap()->is_unmarked(obj) || (new_pointer == (HeapWord*) obj),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
           "Object liveness is wrong.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
    return ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
  assert(UseParallelOldGCDensePrefix ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
         (HeapMaximumCompactionInterval > 1) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
         (MarkSweepAlwaysCompactCount > 1) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
         (forwarding_ptr == new_pointer),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
    "Calculation of new location is incorrect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
  return ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
// Reset objects modified for debug checking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
ParMarkBitMapClosure::IterationStatus
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
PSParallelCompact::ResetObjectsClosure::do_addr(HeapWord* addr, size_t words) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
  // The second arg (words) is not used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
  oop obj = (oop) addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
  obj->init_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
  return ParMarkBitMap::incomplete;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
// Prepare for compaction.  This method is executed once
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
// (i.e., by a single thread) before compaction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
// Save the updated location of the intArrayKlassObj for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
// filling holes in the dense prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
void PSParallelCompact::compact_prologue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  _updated_int_array_klass_obj = (klassOop)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
    summary_data().calc_new_pointer(Universe::intArrayKlassObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
// The initial implementation of this method created a field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
// _next_compaction_space_id in SpaceInfo and initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
// that field in SpaceInfo::initialize_space_info().  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
// required that _next_compaction_space_id be declared a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
// SpaceId in SpaceInfo and that would have required that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
// either SpaceId be declared in a separate class or that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
// it be declared in SpaceInfo.  It didn't seem consistent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
// to declare it in SpaceInfo (didn't really fit logically).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
// Alternatively, defining a separate class to define SpaceId
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
// seem excessive.  This implementation is simple and localizes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
// the knowledge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
PSParallelCompact::SpaceId
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
PSParallelCompact::next_compaction_space_id(SpaceId id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
  assert(id < last_space_id, "id out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  switch (id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
    case perm_space_id :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
      return last_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
    case old_space_id :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
      return eden_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
    case eden_space_id :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
      return from_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
    case from_space_id :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
      return to_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
    case to_space_id :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
      return last_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
      assert(false, "Bad space id");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
      return last_space_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
// Here temporarily for debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
  size_t ParallelCompactData::block_idx(BlockData* block) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
    size_t index = pointer_delta(block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
      PSParallelCompact::summary_data()._block_data, sizeof(BlockData));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
    return index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
#endif