1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "gc/shared/cardTableModRefBS.inline.hpp"
27#include "gc/shared/cardTableRS.hpp"
28#include "memory/allocation.inline.hpp"
29#include "gc/shared/space.inline.hpp"
30
31CardTableModRefBSForCTRS::CardTableModRefBSForCTRS(MemRegion whole_heap) :
32  CardTableModRefBS(
33    whole_heap,
34    BarrierSet::FakeRtti(BarrierSet::CardTableForRS)),
35  // LNC functionality
36  _lowest_non_clean(NULL),
37  _lowest_non_clean_chunk_size(NULL),
38  _lowest_non_clean_base_chunk_index(NULL),
39  _last_LNC_resizing_collection(NULL)
40{ }
41
42void CardTableModRefBSForCTRS::initialize() {
43  CardTableModRefBS::initialize();
44  _lowest_non_clean =
45    NEW_C_HEAP_ARRAY(CardArr, _max_covered_regions, mtGC);
46  _lowest_non_clean_chunk_size =
47    NEW_C_HEAP_ARRAY(size_t, _max_covered_regions, mtGC);
48  _lowest_non_clean_base_chunk_index =
49    NEW_C_HEAP_ARRAY(uintptr_t, _max_covered_regions, mtGC);
50  _last_LNC_resizing_collection =
51    NEW_C_HEAP_ARRAY(int, _max_covered_regions, mtGC);
52  if (_lowest_non_clean == NULL
53      || _lowest_non_clean_chunk_size == NULL
54      || _lowest_non_clean_base_chunk_index == NULL
55      || _last_LNC_resizing_collection == NULL)
56    vm_exit_during_initialization("couldn't allocate an LNC array.");
57  for (int i = 0; i < _max_covered_regions; i++) {
58    _lowest_non_clean[i] = NULL;
59    _lowest_non_clean_chunk_size[i] = 0;
60    _last_LNC_resizing_collection[i] = -1;
61  }
62}
63
64CardTableModRefBSForCTRS::~CardTableModRefBSForCTRS() {
65  if (_lowest_non_clean) {
66    FREE_C_HEAP_ARRAY(CardArr, _lowest_non_clean);
67    _lowest_non_clean = NULL;
68  }
69  if (_lowest_non_clean_chunk_size) {
70    FREE_C_HEAP_ARRAY(size_t, _lowest_non_clean_chunk_size);
71    _lowest_non_clean_chunk_size = NULL;
72  }
73  if (_lowest_non_clean_base_chunk_index) {
74    FREE_C_HEAP_ARRAY(uintptr_t, _lowest_non_clean_base_chunk_index);
75    _lowest_non_clean_base_chunk_index = NULL;
76  }
77  if (_last_LNC_resizing_collection) {
78    FREE_C_HEAP_ARRAY(int, _last_LNC_resizing_collection);
79    _last_LNC_resizing_collection = NULL;
80  }
81}
82
83bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) {
84  return
85    card_is_dirty_wrt_gen_iter(cv) ||
86    _rs->is_prev_nonclean_card_val(cv);
87}
88
89bool CardTableModRefBSForCTRS::card_may_have_been_dirty(jbyte cv) {
90  return
91    cv != clean_card &&
92    (card_is_dirty_wrt_gen_iter(cv) ||
93     CardTableRS::youngergen_may_have_been_dirty(cv));
94}
95
96void CardTableModRefBSForCTRS::non_clean_card_iterate_possibly_parallel(
97  Space* sp,
98  MemRegion mr,
99  OopsInGenClosure* cl,
100  CardTableRS* ct,
101  uint n_threads)
102{
103  if (!mr.is_empty()) {
104    if (n_threads > 0) {
105#if INCLUDE_ALL_GCS
106      non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
107#else  // INCLUDE_ALL_GCS
108      fatal("Parallel gc not supported here.");
109#endif // INCLUDE_ALL_GCS
110    } else {
111      // clear_cl finds contiguous dirty ranges of cards to process and clear.
112
113      // This is the single-threaded version used by DefNew.
114      const bool parallel = false;
115
116      DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
117      ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
118
119      clear_cl.do_MemRegion(mr);
120    }
121  }
122}
123
124