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 
 31 CardTableModRefBSForCTRS::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 
 42 void 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 
 64 CardTableModRefBSForCTRS::~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 
 83 bool 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 
 89 bool 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 
 96 void 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