hotspot/src/share/vm/gc/parallel/cardTableExtension.cpp
author tschatzl
Thu, 28 Jan 2016 13:30:12 +0100
changeset 35877 a2a62511d0f8
parent 35862 411842d0c882
child 46618 d503911aa948
permissions -rw-r--r--
8146987: Improve Parallel GC Full GC by caching results of live_words_in_range() Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value. Reviewed-by: tschatzl, mgerdin, jmasa Contributed-by: ray alex <sky1young@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
35862
411842d0c882 8146395: Add inline qualifier in oop.hpp and fix inlining in gc files
goetz
parents: 35061
diff changeset
     2
 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
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: 2131
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: 6248
diff changeset
    25
#include "precompiled.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    26
#include "gc/parallel/cardTableExtension.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    27
#include "gc/parallel/gcTaskManager.hpp"
35862
411842d0c882 8146395: Add inline qualifier in oop.hpp and fix inlining in gc files
goetz
parents: 35061
diff changeset
    28
#include "gc/parallel/objectStartArray.inline.hpp"
30764
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    29
#include "gc/parallel/parallelScavengeHeap.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    30
#include "gc/parallel/psPromotionManager.inline.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    31
#include "gc/parallel/psScavenge.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    32
#include "gc/parallel/psTasks.hpp"
fec48bf5a827 8079792: GC directory structure cleanup
pliden
parents: 30173
diff changeset
    33
#include "gc/parallel/psYoungGen.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6248
diff changeset
    34
#include "oops/oop.inline.hpp"
24487
71ff0bd674eb 8042737: Introduce umbrella header prefetch.inline.hpp
goetz
parents: 24424
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
// Checks an individual oop for missing precise marks. Mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// may be either dirty or newgen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
class CheckForUnmarkedOops : public OopClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    40
 private:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    41
  PSYoungGen*         _young_gen;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  CardTableExtension* _card_table;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    43
  HeapWord*           _unmarked_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    45
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    46
  template <class T> void do_oop_work(T* p) {
12380
48f69987dbca 7160613: VerifyRememberedSets doesn't work with CompressedOops
stefank
parents: 11174
diff changeset
    47
    oop obj = oopDesc::load_decode_heap_oop(p);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    48
    if (_young_gen->is_in_reserved(obj) &&
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
        !_card_table->addr_is_marked_imprecise(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
      // Don't overwrite the first missing card mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
      if (_unmarked_addr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
        _unmarked_addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    57
 public:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    58
  CheckForUnmarkedOops(PSYoungGen* young_gen, CardTableExtension* card_table) :
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    59
    _young_gen(young_gen), _card_table(card_table), _unmarked_addr(NULL) { }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    60
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    61
  virtual void do_oop(oop* p)       { CheckForUnmarkedOops::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    62
  virtual void do_oop(narrowOop* p) { CheckForUnmarkedOops::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    63
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  bool has_unmarked_oop() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    return _unmarked_addr != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
22551
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 18069
diff changeset
    69
// Checks all objects for the existence of some type of mark,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// precise or imprecise, dirty or newgen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
class CheckForUnmarkedObjects : public ObjectClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    72
 private:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    73
  PSYoungGen*         _young_gen;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  CardTableExtension* _card_table;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  CheckForUnmarkedObjects() {
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
    78
    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    _young_gen = heap->young_gen();
29325
0e86e64c66e5 8069016: Add BarrierSet downcast support
kbarrett
parents: 29208
diff changeset
    80
    _card_table = barrier_set_cast<CardTableExtension>(heap->barrier_set());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    // No point in asserting barrier set type here. Need to make CardTableExtension
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    // a unique barrier set type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  // Card marks are not precise. The current system can leave us with
22551
9bf46d16dcc6 8025856: Fix typos in the GC code
jwilhelm
parents: 18069
diff changeset
    86
  // a mismatch of precise marks and beginning of object marks. This means
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  // we test for missing precise marks first. If any are found, we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  // fail unless the object head is also unmarked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  virtual void do_object(oop obj) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    90
    CheckForUnmarkedOops object_check(_young_gen, _card_table);
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 12380
diff changeset
    91
    obj->oop_iterate_no_header(&object_check);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    if (object_check.has_unmarked_oop()) {
32618
bbbe25551000 8130823: VerifyRememberedSets is an expensive nop in product builds
jwilhelm
parents: 31964
diff changeset
    93
      guarantee(_card_table->addr_is_marked_imprecise(obj), "Found unmarked young_gen object");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
// Checks for precise marking of oops as newgen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
class CheckForPreciseMarks : public OopClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   100
 private:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   101
  PSYoungGen*         _young_gen;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  CardTableExtension* _card_table;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   104
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   105
  template <class T> void do_oop_work(T* p) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   106
    oop obj = oopDesc::load_decode_heap_oop_not_null(p);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   107
    if (_young_gen->is_in_reserved(obj)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   108
      assert(_card_table->addr_is_marked_precise(p), "Found unmarked precise oop");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   109
      _card_table->set_card_newgen(p);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   110
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   111
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   112
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  CheckForPreciseMarks( PSYoungGen* young_gen, CardTableExtension* card_table ) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    _young_gen(young_gen), _card_table(card_table) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   117
  virtual void do_oop(oop* p)       { CheckForPreciseMarks::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   118
  virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
// We get passed the space_top value to prevent us from traversing into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
// the old_gen promotion labs, which cannot be safely parsed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
13924
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   124
// Do not call this method if the space is empty.
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   125
// It is a waste to start tasks and get here only to
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   126
// do no work.  If this method needs to be called
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   127
// when the space is empty, fix the calculation of
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   128
// end_card to allow sp_top == sp->bottom().
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
                                                    MutableSpace* sp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
                                                    HeapWord* space_top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
                                                    PSPromotionManager* pm,
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   134
                                                    uint stripe_number,
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   135
                                                    uint stripe_total) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  int ssize = 128; // Naked constant!  Work unit = 64k.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  int dirty_card_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
13924
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   139
  // It is a waste to get here if empty.
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   140
  assert(sp->bottom() < sp->top(), "Should not be called if empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  oop* sp_top = (oop*)space_top;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  jbyte* start_card = byte_for(sp->bottom());
13924
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   143
  jbyte* end_card   = byte_for(sp_top - 1) + 1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  oop* last_scanned = NULL; // Prevent scanning objects more than once
11174
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   145
  // The width of the stripe ssize*stripe_total must be
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   146
  // consistent with the number of stripes so that the complete slice
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   147
  // is covered.
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   148
  size_t slice_width = ssize * stripe_total;
fccee5238e70 6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents: 7397
diff changeset
   149
  for (jbyte* slice = start_card; slice < end_card; slice += slice_width) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    jbyte* worker_start_card = slice + stripe_number * ssize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    if (worker_start_card >= end_card)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      return; // We're done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    jbyte* worker_end_card = worker_start_card + ssize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    if (worker_end_card > end_card)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      worker_end_card = end_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    // We do not want to scan objects more than once. In order to accomplish
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    // this, we assert that any object with an object head inside our 'slice'
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    // belongs to us. We may need to extend the range of scanned cards if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    // last object continues into the next 'slice'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    // Note! ending cards are exclusive!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    HeapWord* slice_start = addr_for(worker_start_card);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
13924
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   167
#ifdef ASSERT
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   168
    if (GCWorkerDelayMillis > 0) {
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   169
      // Delay 1 worker so that it proceeds after all the work
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   170
      // has been completed.
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   171
      if (stripe_number < 2) {
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   172
        os::sleep(Thread::current(), GCWorkerDelayMillis, false);
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   173
      }
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   174
    }
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   175
#endif
159131321ed4 7199349: NPG: PS: Crash seen in jprt
jmasa
parents: 13728
diff changeset
   176
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    // If there are not objects starting within the chunk, skip it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    if (!start_array->object_starts_in_range(slice_start, slice_end)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    }
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 977
diff changeset
   181
    // Update our beginning addr
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    HeapWord* first_object = start_array->object_start(slice_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    debug_only(oop* first_object_within_slice = (oop*) first_object;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    if (first_object < slice_start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
      last_scanned = (oop*)(first_object + oop(first_object)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      debug_only(first_object_within_slice = last_scanned;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      worker_start_card = byte_for(last_scanned);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    // Update the ending addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    if (slice_end < (HeapWord*)sp_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      // The subtraction is important! An object may start precisely at slice_end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      HeapWord* last_object = start_array->object_start(slice_end - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
      slice_end = last_object + oop(last_object)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
      // worker_end_card is exclusive, so bump it one past the end of last_object's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
      // covered span.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      worker_end_card = byte_for(slice_end) + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
      if (worker_end_card > end_card)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
        worker_end_card = end_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    assert(slice_end <= (HeapWord*)sp_top, "Last object in slice crosses space boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    assert(is_valid_card_address(worker_start_card), "Invalid worker start card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    assert(is_valid_card_address(worker_end_card), "Invalid worker end card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    // Note that worker_start_card >= worker_end_card is legal, and happens when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    // an object spans an entire slice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    assert(worker_start_card <= end_card, "worker start card beyond end card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    assert(worker_end_card <= end_card, "worker end card beyond end card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    jbyte* current_card = worker_start_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    while (current_card < worker_end_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
      // Find an unclean card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
      while (current_card < worker_end_card && card_is_clean(*current_card)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
        current_card++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
      jbyte* first_unclean_card = current_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
      // Find the end of a run of contiguous unclean cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      while (current_card < worker_end_card && !card_is_clean(*current_card)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        while (current_card < worker_end_card && !card_is_clean(*current_card)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
          current_card++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
        if (current_card < worker_end_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
          // Some objects may be large enough to span several cards. If such
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
          // an object has more than one dirty card, separated by a clean card,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
          // we will attempt to scan it twice. The test against "last_scanned"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
          // prevents the redundant object scan, but it does not prevent newly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
          // marked cards from being cleaned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
          HeapWord* last_object_in_dirty_region = start_array->object_start(addr_for(current_card)-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
          size_t size_of_last_object = oop(last_object_in_dirty_region)->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
          HeapWord* end_of_last_object = last_object_in_dirty_region + size_of_last_object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
          jbyte* ending_card_of_last_object = byte_for(end_of_last_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
          assert(ending_card_of_last_object <= worker_end_card, "ending_card_of_last_object is greater than worker_end_card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
          if (ending_card_of_last_object > current_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
            // This means the object spans the next complete card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
            // We need to bump the current_card to ending_card_of_last_object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
            current_card = ending_card_of_last_object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      jbyte* following_clean_card = current_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      if (first_unclean_card < worker_end_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
        oop* p = (oop*) start_array->object_start(addr_for(first_unclean_card));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
        assert((HeapWord*)p <= addr_for(first_unclean_card), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
        // "p" should always be >= "last_scanned" because newly GC dirtied
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
        // cards are no longer scanned again (see comment at end
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
        // of loop on the increment of "current_card").  Test that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
        // hypothesis before removing this code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
        // If this code is removed, deal with the first time through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
        // the loop when the last_scanned is the object starting in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
        // the previous slice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
        assert((p >= last_scanned) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
               (last_scanned == first_object_within_slice),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
               "Should no longer be possible");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
        if (p < last_scanned) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
          // Avoid scanning more than once; this can happen because
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
          // newgen cards set by GC may a different set than the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
          // originally dirty set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
          p = last_scanned;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
        oop* to = (oop*)addr_for(following_clean_card);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        // Test slice_end first!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        if ((HeapWord*)to > slice_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
          to = (oop*)slice_end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        } else if (to > sp_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
          to = sp_top;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
        // we know which cards to scan, now clear them
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
        if (first_unclean_card <= worker_start_card+1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
          first_unclean_card = worker_start_card+1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        if (following_clean_card >= worker_end_card-1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
          following_clean_card = worker_end_card-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
        while (first_unclean_card < following_clean_card) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
          *first_unclean_card++ = clean_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
        const int interval = PrefetchScanIntervalInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
        // scan all objects in the range
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
        if (interval != 0) {
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   286
          while (p < to) {
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   287
            Prefetch::write(p, interval);
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   288
            oop m = oop(p);
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32618
diff changeset
   289
            assert(m->is_oop_or_null(), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m));
29792
8c6fa07f0869 8075957: Reduce calls to the GC specific object visitors in oopDesc
stefank
parents: 29325
diff changeset
   290
            pm->push_contents(m);
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   291
            p += m->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
          }
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   293
          pm->drain_stacks_cond_depth();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
        } else {
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   295
          while (p < to) {
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   296
            oop m = oop(p);
33105
294e48b4f704 8080775: Better argument formatting for assert() and friends
david
parents: 32618
diff changeset
   297
            assert(m->is_oop_or_null(), "Expected an oop or NULL for header field at " PTR_FORMAT, p2i(m));
29792
8c6fa07f0869 8075957: Reduce calls to the GC specific object visitors in oopDesc
stefank
parents: 29325
diff changeset
   298
            pm->push_contents(m);
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   299
            p += m->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
          }
6248
2e661807cef0 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 5892
diff changeset
   301
          pm->drain_stacks_cond_depth();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        last_scanned = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      // "current_card" is still the "following_clean_card" or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      // the current_card is >= the worker_end_card so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      // loop will not execute again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      assert((current_card == following_clean_card) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
             (current_card >= worker_end_card),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
        "current_card should only be incremented if it still equals "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
        "following_clean_card");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
      // Increment current_card so that it is not processed again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
      // It may now be dirty because a old-to-young pointer was
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
      // found on it an updated.  If it is now dirty, it cannot be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
      // be safely cleaned in the next iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
      current_card++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
// This should be called before a scavenge.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
void CardTableExtension::verify_all_young_refs_imprecise() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  CheckForUnmarkedObjects check;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
   325
  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  old_gen->object_iterate(&check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
// This should be called immediately after a scavenge, before mutators resume.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
void CardTableExtension::verify_all_young_refs_precise() {
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
   333
  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  PSOldGen* old_gen = heap->old_gen();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
29325
0e86e64c66e5 8069016: Add BarrierSet downcast support
kbarrett
parents: 29208
diff changeset
   336
  CheckForPreciseMarks check(
0e86e64c66e5 8069016: Add BarrierSet downcast support
kbarrett
parents: 29208
diff changeset
   337
    heap->young_gen(),
0e86e64c66e5 8069016: Add BarrierSet downcast support
kbarrett
parents: 29208
diff changeset
   338
    barrier_set_cast<CardTableExtension>(heap->barrier_set()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 12380
diff changeset
   340
  old_gen->oop_iterate_no_header(&check);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  verify_all_young_refs_precise_helper(old_gen->object_space()->used_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
29325
0e86e64c66e5 8069016: Add BarrierSet downcast support
kbarrett
parents: 29208
diff changeset
   346
  CardTableExtension* card_table =
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
   347
    barrier_set_cast<CardTableExtension>(ParallelScavengeHeap::heap()->barrier_set());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  jbyte* bot = card_table->byte_for(mr.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  jbyte* top = card_table->byte_for(mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  while(bot <= top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    assert(*bot == clean_card || *bot == verify_card, "Found unwanted or unknown card mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    if (*bot == verify_card)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
      *bot = youngergen_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    bot++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
bool CardTableExtension::addr_is_marked_imprecise(void *addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  jbyte* p = byte_for(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  jbyte val = *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  if (card_is_dirty(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  if (card_is_newgen(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  if (card_is_clean(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  assert(false, "Found unhandled card mark type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// Also includes verify_card
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
bool CardTableExtension::addr_is_marked_precise(void *addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  jbyte* p = byte_for(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  jbyte val = *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  if (card_is_newgen(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  if (card_is_verify(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  if (card_is_clean(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  if (card_is_dirty(val))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  assert(false, "Found unhandled card mark type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
// Assumes that only the base or the end changes.  This allows indentification
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
// of the region that is being resized.  The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
// CardTableModRefBS::resize_covered_region() is used for the normal case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
// where the covered regions are growing or shrinking at the high end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
// The method resize_covered_region_by_end() is analogous to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
// CardTableModRefBS::resize_covered_region() but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
// for regions that grow or shrink at the low end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
void CardTableExtension::resize_covered_region(MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  for (int i = 0; i < _cur_covered_regions; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    if (_covered[i].start() == new_region.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
      // Found a covered region with the same start as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
      // new region.  The region is growing or shrinking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
      // from the start of the region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
      resize_covered_region_by_start(new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    if (_covered[i].start() > new_region.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  int changed_region = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  for (int j = 0; j < _cur_covered_regions; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    if (_covered[j].end() == new_region.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
      changed_region = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
      // This is a case where the covered region is growing or shrinking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      // at the start of the region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
      assert(changed_region != -1, "Don't expect to add a covered region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      assert(_covered[changed_region].byte_size() != new_region.byte_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
        "The sizes should be different here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      resize_covered_region_by_end(changed_region, new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  // This should only be a new covered region (where no existing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  // covered region matches at the start or the end).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  assert(_cur_covered_regions < _max_covered_regions,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    "An existing region should have been found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  resize_covered_region_by_start(new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
void CardTableExtension::resize_covered_region_by_start(MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  CardTableModRefBS::resize_covered_region(new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  debug_only(verify_guard();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
void CardTableExtension::resize_covered_region_by_end(int changed_region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
                                                      MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    "Only expect an expansion at the low end at a GC");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  debug_only(verify_guard();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  for (int k = 0; k < _cur_covered_regions; k++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    if (_covered[k].end() == new_region.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
      assert(changed_region == k, "Changed region is incorrect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // Commit new or uncommit old pages, if necessary.
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   461
  if (resize_commit_uncommit(changed_region, new_region)) {
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   462
    // Set the new start of the committed region
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   463
    resize_update_committed_table(changed_region, new_region);
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   464
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  // Update card table entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  resize_update_card_table_entries(changed_region, new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  // Update the covered region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  resize_update_covered_table(changed_region, new_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
35061
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   472
  int ind = changed_region;
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   473
  log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   474
  log_trace(gc, barrier)("    _covered[%d].start(): " INTPTR_FORMAT "  _covered[%d].last(): " INTPTR_FORMAT,
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   475
                ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   476
  log_trace(gc, barrier)("    _committed[%d].start(): " INTPTR_FORMAT "  _committed[%d].last(): " INTPTR_FORMAT,
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   477
                ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   478
  log_trace(gc, barrier)("    byte_for(start): " INTPTR_FORMAT "  byte_for(last): " INTPTR_FORMAT,
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   479
                p2i(byte_for(_covered[ind].start())),  p2i(byte_for(_covered[ind].last())));
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   480
  log_trace(gc, barrier)("    addr_for(start): " INTPTR_FORMAT "  addr_for(last): " INTPTR_FORMAT,
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   481
                p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
be6025ebffea 8145092: Use Unified Logging for the GC logging
brutisso
parents: 33105
diff changeset
   482
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  debug_only(verify_guard();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   486
bool CardTableExtension::resize_commit_uncommit(int changed_region,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
                                                MemRegion new_region) {
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   488
  bool result = false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  // Commit new or uncommit old pages, if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  MemRegion cur_committed = _committed[changed_region];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  assert(_covered[changed_region].end() == new_region.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    "The ends of the regions are expected to match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  // Extend the start of this _committed region to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  // to cover the start of any previous _committed region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  // This forms overlapping regions, but never interior regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  HeapWord* min_prev_start = lowest_prev_committed_start(changed_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  if (min_prev_start < cur_committed.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    // Only really need to set start of "cur_committed" to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
    // the new start (min_prev_start) but assertion checking code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    // below use cur_committed.end() so make it correct.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    MemRegion new_committed =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
        MemRegion(min_prev_start, cur_committed.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    cur_committed = new_committed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
#ifdef ASSERT
30173
13cf7580b000 8077413: Avoid use of Universe::heap() inside collectors
pliden
parents: 29792
diff changeset
   506
  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  assert(cur_committed.start() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
    (HeapWord*) align_size_up((uintptr_t) cur_committed.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
                              os::vm_page_size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
    "Starts should have proper alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  jbyte* new_start = byte_for(new_region.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // Round down because this is for the start address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  HeapWord* new_start_aligned =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
    (HeapWord*)align_size_down((uintptr_t)new_start, os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  // The guard page is always committed and should not be committed over.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // This method is used in cases where the generation is growing toward
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // lower addresses but the guard region is still at the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // card table.  That still makes sense when looking for writes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // off the end of the card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  if (new_start_aligned < cur_committed.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    // Expand the committed region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    // Case A
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
    //                                          |+ guard +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
    //                          |+ cur committed +++++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    //                  |+ new committed +++++++++++++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    // Case B
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
    //                                          |+ guard +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    //                        |+ cur committed +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    //                  |+ new committed +++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    // These are not expected because the calculation of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    // cur committed region and the new committed region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    // share the same end for the covered region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    // Case C
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    //                                          |+ guard +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    //                        |+ cur committed +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
    //                  |+ new committed +++++++++++++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
    // Case D
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
    //                                          |+ guard +|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    //                        |+ cur committed +++++++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    //                  |+ new committed +++++++|
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    HeapWord* new_end_for_commit =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      MIN2(cur_committed.end(), _guard_region.start());
971
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   549
    if(new_start_aligned < new_end_for_commit) {
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   550
      MemRegion new_committed =
f0b20be4165d 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 360
diff changeset
   551
        MemRegion(new_start_aligned, new_end_for_commit);
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 17087
diff changeset
   552
      os::commit_memory_or_exit((char*)new_committed.start(),
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 17087
diff changeset
   553
                                new_committed.byte_size(), !ExecMem,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 17087
diff changeset
   554
                                "card table expansion");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    }
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   556
    result = true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  } else if (new_start_aligned > cur_committed.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    // Shrink the committed region
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   559
#if 0 // uncommitting space is currently unsafe because of the interactions
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   560
      // of growing and shrinking regions.  One region A can uncommit space
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   561
      // that it owns but which is being used by another region B (maybe).
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   562
      // Region B has not committed the space because it was already
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   563
      // committed by region A.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    MemRegion uncommit_region = committed_unique_to_self(changed_region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      MemRegion(cur_committed.start(), new_start_aligned));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    if (!uncommit_region.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
      if (!os::uncommit_memory((char*)uncommit_region.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
                               uncommit_region.byte_size())) {
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   569
        // If the uncommit fails, ignore it.  Let the
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   570
        // committed table resizing go even though the committed
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   571
        // table will over state the committed space.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    }
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   574
#else
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   575
    assert(!result, "Should be false with current workaround");
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   576
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  assert(_committed[changed_region].end() == cur_committed.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    "end should not change");
5892
477b32b9d021 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 5547
diff changeset
   580
  return result;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
void CardTableExtension::resize_update_committed_table(int changed_region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
                                                       MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  jbyte* new_start = byte_for(new_region.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  // Set the new start of the committed region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  HeapWord* new_start_aligned =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    (HeapWord*)align_size_down((uintptr_t)new_start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
                             os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  MemRegion new_committed = MemRegion(new_start_aligned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    _committed[changed_region].end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  _committed[changed_region] = new_committed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  _committed[changed_region].set_start(new_start_aligned);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
void CardTableExtension::resize_update_card_table_entries(int changed_region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
                                                          MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  debug_only(verify_guard();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  MemRegion original_covered = _covered[changed_region];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  // Initialize the card entries.  Only consider the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  // region covered by the card table (_whole_heap)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  jbyte* entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  if (new_region.start() < _whole_heap.start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    entry = byte_for(_whole_heap.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
    entry = byte_for(new_region.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  jbyte* end = byte_for(original_covered.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  // If _whole_heap starts at the original covered regions start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  // this loop will not execute.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  while (entry < end) { *entry++ = clean_card; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
void CardTableExtension::resize_update_covered_table(int changed_region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
                                                     MemRegion new_region) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  // Update the covered region
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  _covered[changed_region].set_start(new_region.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  _covered[changed_region].set_word_size(new_region.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  // reorder regions.  There should only be at most 1 out
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  // of order.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  for (int i = _cur_covered_regions-1 ; i > 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    if (_covered[i].start() < _covered[i-1].start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
        MemRegion covered_mr = _covered[i-1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
        _covered[i-1] = _covered[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
        _covered[i] = covered_mr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
        MemRegion committed_mr = _committed[i-1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
      _committed[i-1] = _committed[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
      _committed[i] = committed_mr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  for (int m = 0; m < _cur_covered_regions-1; m++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    assert(_covered[m].start() <= _covered[m+1].start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
      "Covered regions out of order");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    assert(_committed[m].start() <= _committed[m+1].start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      "Committed regions out of order");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
// Returns the start of any committed region that is lower than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
// the target committed region (index ind) and that intersects the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
// target region.  If none, return start of target region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
//      -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
//      |           |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
//      -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
//              ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
//              | target   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
//              ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
//                               -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
//                               |           |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
//                               -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
//      ^ returns this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
//      -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
//      |           |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
//      -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
//                      ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
//                      | target   |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
//                      ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
//                               -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
//                               |           |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
//                               -------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
//                      ^ returns this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
HeapWord* CardTableExtension::lowest_prev_committed_start(int ind) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  assert(_cur_covered_regions >= 0, "Expecting at least on region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  HeapWord* min_start = _committed[ind].start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  for (int j = 0; j < ind; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
    HeapWord* this_start = _committed[j].start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    if ((this_start < min_start) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
        !(_committed[j].intersection(_committed[ind])).is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
       min_start = this_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  return min_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
}