blob: b4231dbc4c79dc301d0ee994add9604e93512c88 [file] [edit]
/*
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_SERIAL_CARDTABLERS_HPP
#define SHARE_GC_SERIAL_CARDTABLERS_HPP
#include "gc/shared/cardTable.hpp"
#include "memory/memRegion.hpp"
#include "oops/oop.hpp"
class OldGenScanClosure;
class TenuredGeneration;
// This RemSet uses a card table both as shared data structure
// for a mod ref barrier set and for the rem set information.
class CardTableRS : public CardTable {
friend class VMStructs;
static bool is_dirty(const CardValue* const v) {
return !is_clean(v);
}
static bool is_clean(const CardValue* const v) {
return *v == clean_card_val();
}
static void clear_cards(CardValue* start, CardValue* end);
static CardValue* find_first_dirty_card(CardValue* start_card,
CardValue* end_card);
template<typename Func>
CardValue* find_first_clean_card(CardValue* start_card,
CardValue* end_card,
Func& object_start);
public:
CardTableRS(MemRegion whole_heap);
void scan_old_to_young_refs(TenuredGeneration* tg, HeapWord* saved_top);
void inline_write_ref_field_gc(void* field) {
CardValue* byte = byte_for(field);
*byte = dirty_card_val();
}
bool is_dirty_for_addr(const void* p) const {
CardValue* card = byte_for(p);
return is_dirty(card);
}
void verify();
// Update old gen cards to maintain old-to-young-pointer invariant: Clear
// the old generation card table completely if the young generation had been
// completely evacuated, otherwise dirties the whole old generation to
// conservatively not loose any old-to-young pointer.
void maintain_old_to_young_invariant(TenuredGeneration* old_gen, bool is_young_gen_empty);
// Iterate over the portion of the card-table which covers the given
// region mr in the given space and apply cl to any dirty sub-regions
// of mr. Clears the dirty cards as they are processed.
void non_clean_card_iterate(TenuredGeneration* tg,
MemRegion mr,
OldGenScanClosure* cl);
bool is_in_young(const void* p) const override;
};
#endif // SHARE_GC_SERIAL_CARDTABLERS_HPP