hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp
author tschatzl
Tue, 16 Sep 2014 10:28:15 +0200
changeset 26701 f8ff74a6c058
parent 25889 221296ac4359
child 27682 dbd1c3f92130
permissions -rw-r--r--
8052172: Evacuation failure handling in G1 does not evacuate all objects if -XX:-G1DeferredRSUpdate is set Summary: Remove -XX:-G1DeferredRSUpdate functionality as it is racy. During evacuation failure handling, threads where evacuation failure handling occurred may try to add remembered sets to regions which remembered sets are currently being scanned. The iterator to handle the remembered set scan does not support addition of entries during scan and so may skip valid references. Reviewed-by: iveresov, brutisso, mgerdin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25482
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     1
/*
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     4
 *
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     7
 * published by the Free Software Foundation.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     8
 *
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    13
 * accompanied this code).
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    14
 *
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    18
 *
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    21
 * questions.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    22
 *
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    23
 */
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    24
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    25
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    26
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    27
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    28
#include "gc_implementation/g1/g1ParScanThreadState.hpp"
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    29
#include "gc_implementation/g1/g1RemSet.inline.hpp"
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    30
#include "oops/oop.inline.hpp"
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    31
25483
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    32
template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from) {
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    33
  assert(!oopDesc::is_null(oopDesc::load_decode_heap_oop(p)),
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    34
         "Reference should not be NULL here as such are never pushed to the task queue.");
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    35
  oop obj = oopDesc::load_decode_heap_oop_not_null(p);
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    36
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    37
  // Although we never intentionally push references outside of the collection
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    38
  // set, due to (benign) races in the claim mechanism during RSet scanning more
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    39
  // than one thread might claim the same card. So the same card may be
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    40
  // processed multiple times. So redo this check.
25889
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    41
  G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj);
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    42
  if (in_cset_state == G1CollectedHeap::InCSet) {
25483
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    43
    oop forwardee;
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    44
    if (obj->is_forwarded()) {
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    45
      forwardee = obj->forwardee();
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    46
    } else {
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    47
      forwardee = copy_to_survivor_space(obj);
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    48
    }
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    49
    oopDesc::encode_store_heap_oop(p, forwardee);
25889
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    50
  } else if (in_cset_state == G1CollectedHeap::IsHumongous) {
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    51
    _g1h->set_humongous_is_live(obj);
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    52
  } else {
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    53
    assert(in_cset_state == G1CollectedHeap::InNeither,
221296ac4359 8027959: Early reclamation of large objects in G1
tschatzl
parents: 25483
diff changeset
    54
           err_msg("In_cset_state must be InNeither here, but is %d", in_cset_state));
25483
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    55
  }
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    56
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    57
  assert(obj != NULL, "Must be");
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    58
  update_rs(from, p, queue_num());
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    59
}
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
    60
25482
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    61
inline void G1ParScanThreadState::do_oop_partial_array(oop* p) {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    62
  assert(has_partial_array_mask(p), "invariant");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    63
  oop from_obj = clear_partial_array_mask(p);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    64
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    65
  assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap.");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    66
  assert(from_obj->is_objArray(), "must be obj array");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    67
  objArrayOop from_obj_array = objArrayOop(from_obj);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    68
  // The from-space object contains the real length.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    69
  int length                 = from_obj_array->length();
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    70
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    71
  assert(from_obj->is_forwarded(), "must be forwarded");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    72
  oop to_obj                 = from_obj->forwardee();
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    73
  assert(from_obj != to_obj, "should not be chunking self-forwarded objects");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    74
  objArrayOop to_obj_array   = objArrayOop(to_obj);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    75
  // We keep track of the next start index in the length field of the
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    76
  // to-space object.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    77
  int next_index             = to_obj_array->length();
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    78
  assert(0 <= next_index && next_index < length,
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    79
         err_msg("invariant, next index: %d, length: %d", next_index, length));
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    80
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    81
  int start                  = next_index;
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    82
  int end                    = length;
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    83
  int remainder              = end - start;
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    84
  // We'll try not to push a range that's smaller than ParGCArrayScanChunk.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    85
  if (remainder > 2 * ParGCArrayScanChunk) {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    86
    end = start + ParGCArrayScanChunk;
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    87
    to_obj_array->set_length(end);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    88
    // Push the remainder before we process the range in case another
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    89
    // worker has run out of things to do and can steal it.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    90
    oop* from_obj_p = set_partial_array_mask(from_obj);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    91
    push_on_queue(from_obj_p);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    92
  } else {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    93
    assert(length == end, "sanity");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    94
    // We'll process the final range for this object. Restore the length
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    95
    // so that the heap remains parsable in case of evacuation failure.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    96
    to_obj_array->set_length(end);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    97
  }
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    98
  _scanner.set_region(_g1h->heap_region_containing_raw(to_obj));
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
    99
  // Process indexes [start,end). It will also process the header
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   100
  // along with the first chunk (i.e., the chunk with start == 0).
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   101
  // Note that at this point the length field of to_obj_array is not
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   102
  // correct given that we are using it to keep track of the next
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   103
  // start index. oop_iterate_range() (thankfully!) ignores the length
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   104
  // field and only relies on the start / end parameters.  It does
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   105
  // however return the size of the object which will be incorrect. So
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   106
  // we have to ignore it even if we wanted to use it.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   107
  to_obj_array->oop_iterate_range(&_scanner, start, end);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   108
}
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   109
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   110
template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   111
  if (!has_partial_array_mask(ref_to_scan)) {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   112
    // Note: we can use "raw" versions of "region_containing" because
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   113
    // "obj_to_scan" is definitely in the heap, and is not in a
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   114
    // humongous region.
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   115
    HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   116
    do_oop_evac(ref_to_scan, r);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   117
  } else {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   118
    do_oop_partial_array((oop*)ref_to_scan);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   119
  }
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   120
}
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   121
25483
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   122
inline void G1ParScanThreadState::dispatch_reference(StarTask ref) {
25482
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   123
  assert(verify_task(ref), "sanity");
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   124
  if (ref.is_narrow()) {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   125
    deal_with_reference((narrowOop*)ref);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   126
  } else {
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   127
    deal_with_reference((oop*)ref);
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   128
  }
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   129
}
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   130
25483
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   131
void G1ParScanThreadState::steal_and_trim_queue(RefToScanQueueSet *task_queues) {
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   132
  StarTask stolen_task;
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   133
  while (task_queues->steal(queue_num(), hash_seed(), stolen_task)) {
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   134
    assert(verify_task(stolen_task), "sanity");
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   135
    dispatch_reference(stolen_task);
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   136
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   137
    // We've just processed a reference and we might have made
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   138
    // available new entries on the queues. So we have to make sure
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   139
    // we drain the queues as necessary.
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   140
    trim_queue();
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   141
  }
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   142
}
962ccf95c515 8035401: Fix visibility of G1ParScanThreadState members
tschatzl
parents: 25482
diff changeset
   143
25482
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   144
#endif /* SHARE_VM_GC_IMPLEMENTATION_G1_G1PARSCANTHREADSTATE_INLINE_HPP */
b69656f26643 8035400: Move G1ParScanThreadState into its own files
tschatzl
parents:
diff changeset
   145