hotspot/src/share/vm/gc/parallel/psMarkSweepDecorator.cpp
author tschatzl
Thu, 28 Jan 2016 13:30:12 +0100
changeset 35877 a2a62511d0f8
parent 30764 fec48bf5a827
child 37238 3d0a96116bff
permissions -rw-r--r--
8146987: Improve Parallel GC Full GC by caching results of live_words_in_range() Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value. Reviewed-by: tschatzl, mgerdin, jmasa Contributed-by: ray alex <sky1young@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
29792
8c6fa07f0869 8075957: Reduce calls to the GC specific object visitors in oopDesc
stefank
parents: 24487
diff changeset
     2
 * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2105
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2105
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2105
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "classfile/systemDictionary.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    27
#include "gc/parallel/objectStartArray.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    28
#include "gc/parallel/parallelScavengeHeap.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    29
#include "gc/parallel/psMarkSweep.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    30
#include "gc/parallel/psMarkSweepDecorator.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    31
#include "gc/serial/markSweep.inline.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    32
#include "gc/shared/liveRange.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    33
#include "gc/shared/spaceDecorator.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "oops/oop.inline.hpp"
24487
71ff0bd674eb 8042737: Introduce umbrella header prefetch.inline.hpp
goetz
parents: 22234
diff changeset
    35
#include "runtime/prefetch.inline.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
void PSMarkSweepDecorator::set_destination_decorator_tenured() {
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
    41
  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  _destination_decorator = heap->old_gen()->object_mark_sweep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
void PSMarkSweepDecorator::advance_destination_decorator() {
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
    46
  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  assert(_destination_decorator != NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  PSMarkSweepDecorator* first = heap->old_gen()->object_mark_sweep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  PSMarkSweepDecorator* second = heap->young_gen()->eden_mark_sweep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  PSMarkSweepDecorator* third = heap->young_gen()->from_mark_sweep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  PSMarkSweepDecorator* fourth = heap->young_gen()->to_mark_sweep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  if ( _destination_decorator == first ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    _destination_decorator = second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  } else if ( _destination_decorator == second ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    _destination_decorator = third;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  } else if ( _destination_decorator == third ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    _destination_decorator = fourth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    fatal("PSMarkSweep attempting to advance past last compaction area");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
PSMarkSweepDecorator* PSMarkSweepDecorator::destination_decorator() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  assert(_destination_decorator != NULL, "Sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  return _destination_decorator;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
// FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
// The object forwarding code is duplicated. Factor this out!!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
// This method "precompacts" objects inside its space to dest. It places forwarding
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
// pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
// finish by compacting into our own space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
void PSMarkSweepDecorator::precompact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // Reset our own compact top.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  set_compaction_top(space()->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  /* We allow some amount of garbage towards the bottom of the space, so
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
   * we don't start compacting before there is a significant gain to be made.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
   * Occasionally, we want to ensure a full compaction, which is determined
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
   * by the MarkSweepAlwaysCompactCount parameter. This is a significant
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
   * performance improvement!
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
   */
17392
2f967c0e4246 6843347: Boundary values in some public GC options cause crashes
tschatzl
parents: 15088
diff changeset
    89
  bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
1557
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
    91
  size_t allowed_deadspace = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  if (skip_dead) {
1557
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
    93
    const size_t ratio = allowed_dead_ratio();
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
    94
    allowed_deadspace = space()->capacity_in_words() * ratio / 100;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  // Fetch the current destination decorator
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  PSMarkSweepDecorator* dest = destination_decorator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  ObjectStartArray* start_array = dest->start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  HeapWord* compact_top = dest->compaction_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  HeapWord* compact_end = dest->space()->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  HeapWord* q = space()->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  HeapWord* t = space()->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  HeapWord*  end_of_live= q;    /* One byte beyond the last byte of the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
                                   live object. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  HeapWord*  first_dead = space()->end(); /* The first dead object. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  LiveRange* liveRange  = NULL; /* The current live range, recorded in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
                                   first header of preceding free area. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  _first_dead = first_dead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  const intx interval = PrefetchScanIntervalInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  while (q < t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    assert(oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
           oop(q)->mark()->has_bias_pattern(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
           "these are the only valid states during a mark sweep");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    if (oop(q)->is_gc_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
      /* prefetch beyond q */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
      Prefetch::write(q, interval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
      size_t size = oop(q)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
      size_t compaction_max_size = pointer_delta(compact_end, compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      // This should only happen if a space in the young gen overflows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
      // old gen. If that should happen, we null out the start_array, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
      // the young spaces are not covered by one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
      while(size > compaction_max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
        // First record the last compact_top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
        dest->set_compaction_top(compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
        // Advance to the next compaction decorator
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
        advance_destination_decorator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        dest = destination_decorator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
        // Update compaction info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
        start_array = dest->start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
        compact_top = dest->compaction_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
        compact_end = dest->space()->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
        assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
        assert(compact_end > compact_top, "Must always be space remaining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
        compaction_max_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
          pointer_delta(compact_end, compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      // store the forwarding pointer into the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      if (q != compact_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
        oop(q)->forward_to(oop(compact_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
        assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      } else {
1406
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   153
        // if the object isn't moving we can just set the mark to the default
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   154
        // mark and handle it specially later on.
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   155
        oop(q)->init_mark();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
        assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      // Update object start array
1406
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   160
      if (start_array) {
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   161
        start_array->allocate_block(compact_top);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
      compact_top += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
      assert(compact_top <= dest->space()->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
        "Exceeding space in destination");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
      q += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
      end_of_live = q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
      /* run over all the contiguous dead objects */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
      HeapWord* end = q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
        /* prefetch beyond end */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
        Prefetch::write(end, interval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
        end += oop(end)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
      } while (end < t && (!oop(end)->is_gc_marked()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      /* see if we might want to pretend this object is alive so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
       * we don't have to compact quite as often.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
       */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
      if (allowed_deadspace > 0 && q == compact_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
        size_t sz = pointer_delta(end, q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
        if (insert_deadspace(allowed_deadspace, q, sz)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
          size_t compaction_max_size = pointer_delta(compact_end, compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
          // This should only happen if a space in the young gen overflows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
          // old gen. If that should happen, we null out the start_array, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
          // the young spaces are not covered by one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
          while (sz > compaction_max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
            // First record the last compact_top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
            dest->set_compaction_top(compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
            // Advance to the next compaction decorator
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
            advance_destination_decorator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
            dest = destination_decorator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
            // Update compaction info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
            start_array = dest->start_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
            compact_top = dest->compaction_top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
            compact_end = dest->space()->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
            assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
            assert(compact_end > compact_top, "Must always be space remaining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
            compaction_max_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
              pointer_delta(compact_end, compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
          // store the forwarding pointer into the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
          if (q != compact_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
            oop(q)->forward_to(oop(compact_top));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
            assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
            // if the object isn't moving we can just set the mark to the default
1406
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   214
            // mark and handle it specially later on.
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   215
            oop(q)->init_mark();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
            assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
1406
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   219
          // Update object start array
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   220
          if (start_array) {
e5e2b519fc11 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 977
diff changeset
   221
            start_array->allocate_block(compact_top);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
          compact_top += sz;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
          assert(compact_top <= dest->space()->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
            "Exceeding space in destination");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
          q = end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
          end_of_live = end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
          continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
      /* for the previous LiveRange, record the end of the live objects. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
      if (liveRange) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
        liveRange->set_end(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
      /* record the current LiveRange object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
       * liveRange->start() is overlaid on the mark word.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
       */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      liveRange = (LiveRange*)q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      liveRange->set_start(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      liveRange->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      /* see if this is the first dead region. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      if (q < first_dead) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
        first_dead = q;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      /* move on to the next object */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
      q = end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  assert(q == t, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  if (liveRange != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    liveRange->set_end(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  _end_of_live = end_of_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  if (end_of_live < first_dead) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    first_dead = end_of_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  _first_dead = first_dead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  // Update compaction top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  dest->set_compaction_top(compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
1557
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
   270
bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
   271
                                            HeapWord* q, size_t deadlength) {
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
   272
  if (allowed_deadspace_words >= deadlength) {
13878a2edfef 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 1406
diff changeset
   273
    allowed_deadspace_words -= deadlength;
1668
8ec481b8f514 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 1557
diff changeset
   274
    CollectedHeap::fill_with_object(q, deadlength);
8ec481b8f514 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 1557
diff changeset
   275
    oop(q)->set_mark(oop(q)->mark()->set_marked());
8ec481b8f514 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 1557
diff changeset
   276
    assert((int) deadlength == oop(q)->size(), "bad filler object size");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    // Recall that we required "q == compaction_top".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    allowed_deadspace_words = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
void PSMarkSweepDecorator::adjust_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // adjust all the interior pointers to point at the new locations of objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // Used by MarkSweep::mark_sweep_phase3()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  HeapWord* q = space()->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  HeapWord* t = _end_of_live;  // Established by "prepare_for_compaction".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  assert(_first_dead <= _end_of_live, "Stands to reason, no?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  if (q < t && _first_dead > q &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
      !oop(q)->is_gc_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    // we have a chunk of the space which hasn't moved and we've
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    // reinitialized the mark word during the previous pass, so we can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    // use is_gc_marked for the traversal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    HeapWord* end = _first_dead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    while (q < end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      // point all the oops to the new location
29792
8c6fa07f0869 8075957: Reduce calls to the GC specific object visitors in oopDesc
stefank
parents: 24487
diff changeset
   303
      size_t size = MarkSweep::adjust_pointers(oop(q));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      q += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    if (_first_dead == t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      q = t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      // $$$ This is funky.  Using this to read the previously written
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
      // LiveRange.  See also use below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
      q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  const intx interval = PrefetchScanIntervalInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  debug_only(HeapWord* prev_q = NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  while (q < t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    // prefetch beyond q
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    Prefetch::write(q, interval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    if (oop(q)->is_gc_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
      // q is alive
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
      // point all the oops to the new location
29792
8c6fa07f0869 8075957: Reduce calls to the GC specific object visitors in oopDesc
stefank
parents: 24487
diff changeset
   324
      size_t size = MarkSweep::adjust_pointers(oop(q));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      debug_only(prev_q = q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
      q += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      // q is not a live object, so its mark should point at the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
      // live object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
      debug_only(prev_q = q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
      q = (HeapWord*) oop(q)->mark()->decode_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
      assert(q > prev_q, "we should be moving forward through memory");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  assert(q == t, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // Copy all live objects to their new location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // Used by MarkSweep::mark_sweep_phase4()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  HeapWord*       q = space()->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  HeapWord* const t = _end_of_live;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  debug_only(HeapWord* prev_q = NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  if (q < t && _first_dead > q &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
      !oop(q)->is_gc_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    // we have a chunk of the space which hasn't moved and we've reinitialized the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    // mark word during the previous pass, so we can't use is_gc_marked for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    // traversal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    HeapWord* const end = _first_dead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    while (q < end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
      size_t size = oop(q)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
      assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
      debug_only(prev_q = q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
      q += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    if (_first_dead == t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
      q = t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
      // $$$ Funky
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  const intx scan_interval = PrefetchScanIntervalInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  const intx copy_interval = PrefetchCopyIntervalInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  while (q < t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    if (!oop(q)->is_gc_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
      // mark is pointer to next marked oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      debug_only(prev_q = q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      q = (HeapWord*) oop(q)->mark()->decode_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
      assert(q > prev_q, "we should be moving forward through memory");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
      // prefetch beyond q
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
      Prefetch::read(q, scan_interval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      // size and destination
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      size_t size = oop(q)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
      HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
      // prefetch beyond compaction_top
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
      Prefetch::write(compaction_top, copy_interval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
      // copy object and reinit its mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
      assert(q != compaction_top, "everything in this pass should be moving");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
      Copy::aligned_conjoint_words(q, compaction_top, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
      oop(compaction_top)->init_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
      assert(oop(compaction_top)->klass() != NULL, "should have a class");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
      debug_only(prev_q = q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
      q += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
         "should point inside space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  space()->set_top(compaction_top());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   406
  if (mangle_free_space) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   407
    space()->mangle_unused_area();
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   408
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
}