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