/*
* Copyright ( c ) 1997 , 2020 , 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_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
#define SHARE_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/g1CardSet.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/bitMap.inline.hpp"
void HeapRegionRemSet::set_state_empty() {
guarantee(SafepointSynchronize::is_at_safepoint() || !is_tracked(),
"Should only set to Untracked during safepoint but is %s." , get_state_str());
if (_state == Untracked) {
return ;
}
clear_fcc();
_state = Untracked;
}
void HeapRegionRemSet::set_state_updating() {
guarantee(SafepointSynchronize::is_at_safepoint() && !is_tracked(),
"Should only set to Updating from Untracked during safepoint but is %s" , get_state_str());
clear_fcc();
_state = Updating;
}
void HeapRegionRemSet::set_state_complete() {
clear_fcc();
_state = Complete;
}
template <typename Closure>
class G1ContainerCardsOrRanges {
Closure& _cl;
uint _region_idx;
uint _offset;
public :
G1ContainerCardsOrRanges(Closure& cl, uint region_idx, uint offset) : _cl(cl), _region_idx(region_idx), _offset(offset) { }
bool start_iterate(uint tag) {
return _cl.start_iterate(tag, _region_idx);
}
void operator ()(uint card_idx) {
_cl.do_card(card_idx + _offset);
}
void operator ()(uint card_idx, uint length) {
_cl.do_card_range(card_idx + _offset, length);
}
};
template <typename Closure, template <typename > class CardOrRanges>
class G1HeapRegionRemSetMergeCardClosure : public G1CardSet::ContainerPtrClosure {
G1CardSet* _card_set;
Closure& _cl;
uint _log_card_regions_per_region;
uint _card_regions_per_region_mask;
uint _log_card_region_size;
public :
G1HeapRegionRemSetMergeCardClosure(G1CardSet* card_set,
Closure& cl,
uint log_card_regions_per_region,
uint log_card_region_size) :
_card_set(card_set),
_cl(cl),
_log_card_regions_per_region(log_card_regions_per_region),
_card_regions_per_region_mask((1 << log_card_regions_per_region) - 1 ),
_log_card_region_size(log_card_region_size) {
}
void do_containerptr(uint card_region_idx, size_t num_occupied, G1CardSet::ContainerPtr container) override {
CardOrRanges<Closure> cl(_cl,
card_region_idx >> _log_card_regions_per_region,
(card_region_idx & _card_regions_per_region_mask) << _log_card_region_size);
_card_set->iterate_cards_or_ranges_in_container(container, cl);
}
};
template <class CardOrRangeVisitor>
inline void HeapRegionRemSet::iterate_for_merge(CardOrRangeVisitor& cl) {
G1HeapRegionRemSetMergeCardClosure<CardOrRangeVisitor, G1ContainerCardsOrRanges> cl2(&_card_set,
cl,
_card_set.config()->log2_card_regions_per_heap_region(),
_card_set.config()->log2_cards_per_card_region());
_card_set.iterate_containers(&cl2, true /* at_safepoint */);
}
uintptr_t HeapRegionRemSet::to_card(OopOrNarrowOopStar from) const {
return pointer_delta(from, _heap_base_address, 1 ) >> CardTable::card_shift();
}
void HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) {
assert(_state != Untracked, "must be" );
uint cur_idx = _hr->hrm_index();
uintptr_t from_card = uintptr_t(from) >> CardTable::card_shift();
if (G1FromCardCache::contains_or_replace(tid, cur_idx, from_card)) {
// We can't check whether the card is in the remembered set - the card container
// may be coarsened just now.
//assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from));
return ;
}
_card_set.add_card(to_card(from));
}
bool HeapRegionRemSet::contains_reference(OopOrNarrowOopStar from) {
return _card_set.contains_card(to_card(from));
}
void HeapRegionRemSet::print_info(outputStream* st, OopOrNarrowOopStar from) {
_card_set.print_info(st, to_card(from));
}
#endif // SHARE_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
Messung V0.5 in Prozent C=85 H=100 G=92
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-09-11)
¤
*© Formatika GbR, Deutschland