mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-11 16:33:42 +00:00
8272147: Consolidate preserved marks handling with other STW collectors
Reviewed-by: tschatzl, ayang, rkennke
This commit is contained in:
parent
6cd166a284
commit
07275072aa
@ -43,6 +43,7 @@
|
||||
#include "gc/shared/genCollectedHeap.hpp"
|
||||
#include "gc/shared/generation.hpp"
|
||||
#include "gc/shared/modRefBarrierSet.hpp"
|
||||
#include "gc/shared/preservedMarks.inline.hpp"
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/referenceProcessorPhaseTimes.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
@ -140,6 +141,8 @@ void GenMarkSweep::allocate_stacks() {
|
||||
|
||||
_preserved_marks = (PreservedMark*)scratch;
|
||||
_preserved_count = 0;
|
||||
|
||||
_preserved_overflow_stack_set.init(1);
|
||||
}
|
||||
|
||||
|
||||
@ -147,7 +150,7 @@ void GenMarkSweep::deallocate_stacks() {
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
gch->release_scratch();
|
||||
|
||||
_preserved_overflow_stack.clear(true);
|
||||
_preserved_overflow_stack_set.reclaim();
|
||||
_marking_stack.clear();
|
||||
_objarray_stack.clear(true);
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ uint MarkSweep::_total_invocations = 0;
|
||||
Stack<oop, mtGC> MarkSweep::_marking_stack;
|
||||
Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack;
|
||||
|
||||
Stack<PreservedMark, mtGC> MarkSweep::_preserved_overflow_stack;
|
||||
PreservedMarksSet MarkSweep::_preserved_overflow_stack_set(false /* in_c_heap */);
|
||||
size_t MarkSweep::_preserved_count = 0;
|
||||
size_t MarkSweep::_preserved_count_max = 0;
|
||||
PreservedMark* MarkSweep::_preserved_marks = nullptr;
|
||||
@ -142,14 +142,6 @@ template <class T> void MarkSweep::follow_root(T* p) {
|
||||
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
|
||||
void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
|
||||
|
||||
void PreservedMark::adjust_pointer() {
|
||||
MarkSweep::adjust_pointer(&_obj);
|
||||
}
|
||||
|
||||
void PreservedMark::restore() {
|
||||
_obj->set_mark(_mark);
|
||||
}
|
||||
|
||||
// We preserve the mark which should be replaced at the end and the location
|
||||
// that it will go. Note that the object that this markWord belongs to isn't
|
||||
// currently at that address but it will be after phase4
|
||||
@ -161,7 +153,7 @@ void MarkSweep::preserve_mark(oop obj, markWord mark) {
|
||||
if (_preserved_count < _preserved_count_max) {
|
||||
_preserved_marks[_preserved_count++] = PreservedMark(obj, mark);
|
||||
} else {
|
||||
_preserved_overflow_stack.push(PreservedMark(obj, mark));
|
||||
_preserved_overflow_stack_set.get()->push_always(obj, mark);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,30 +197,23 @@ AdjustPointerClosure MarkSweep::adjust_pointer_closure;
|
||||
void MarkSweep::adjust_marks() {
|
||||
// adjust the oops we saved earlier
|
||||
for (size_t i = 0; i < _preserved_count; i++) {
|
||||
_preserved_marks[i].adjust_pointer();
|
||||
PreservedMarks::adjust_preserved_mark(_preserved_marks + i);
|
||||
}
|
||||
|
||||
// deal with the overflow stack
|
||||
StackIterator<PreservedMark, mtGC> iter(_preserved_overflow_stack);
|
||||
while (!iter.is_empty()) {
|
||||
PreservedMark* p = iter.next_addr();
|
||||
p->adjust_pointer();
|
||||
}
|
||||
_preserved_overflow_stack_set.get()->adjust_during_full_gc();
|
||||
}
|
||||
|
||||
void MarkSweep::restore_marks() {
|
||||
log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_overflow_stack.size());
|
||||
log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_overflow_stack_set.get()->size());
|
||||
|
||||
// restore the marks we saved earlier
|
||||
for (size_t i = 0; i < _preserved_count; i++) {
|
||||
_preserved_marks[i].restore();
|
||||
_preserved_marks[i].set_mark();
|
||||
}
|
||||
|
||||
// deal with the overflow
|
||||
while (!_preserved_overflow_stack.is_empty()) {
|
||||
PreservedMark p = _preserved_overflow_stack.pop();
|
||||
p.restore();
|
||||
}
|
||||
_preserved_overflow_stack_set.restore(nullptr);
|
||||
}
|
||||
|
||||
MarkSweep::IsAliveClosure MarkSweep::is_alive;
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#define SHARE_GC_SERIAL_MARKSWEEP_HPP
|
||||
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "gc/shared/preservedMarks.inline.hpp"
|
||||
#include "gc/shared/referenceProcessor.hpp"
|
||||
#include "gc/shared/stringdedup/stringDedup.hpp"
|
||||
#include "gc/shared/taskqueue.hpp"
|
||||
@ -99,7 +100,7 @@ class MarkSweep : AllStatic {
|
||||
static Stack<ObjArrayTask, mtGC> _objarray_stack;
|
||||
|
||||
// Space for storing/restoring mark word
|
||||
static Stack<PreservedMark, mtGC> _preserved_overflow_stack;
|
||||
static PreservedMarksSet _preserved_overflow_stack_set;
|
||||
static size_t _preserved_count;
|
||||
static size_t _preserved_count_max;
|
||||
static PreservedMark* _preserved_marks;
|
||||
@ -186,15 +187,4 @@ class AdjustPointerClosure: public BasicOopIterateClosure {
|
||||
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
|
||||
};
|
||||
|
||||
class PreservedMark {
|
||||
private:
|
||||
oop _obj;
|
||||
markWord _mark;
|
||||
|
||||
public:
|
||||
PreservedMark(oop obj, markWord mark) : _obj(obj), _mark(mark) {}
|
||||
void adjust_pointer();
|
||||
void restore();
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_SERIAL_MARKSWEEP_HPP
|
||||
|
||||
@ -34,21 +34,24 @@
|
||||
|
||||
void PreservedMarks::restore() {
|
||||
while (!_stack.is_empty()) {
|
||||
const OopAndMarkWord elem = _stack.pop();
|
||||
const PreservedMark elem = _stack.pop();
|
||||
elem.set_mark();
|
||||
}
|
||||
assert_empty();
|
||||
}
|
||||
|
||||
void PreservedMarks::adjust_during_full_gc() {
|
||||
StackIterator<OopAndMarkWord, mtGC> iter(_stack);
|
||||
while (!iter.is_empty()) {
|
||||
OopAndMarkWord* elem = iter.next_addr();
|
||||
void PreservedMarks::adjust_preserved_mark(PreservedMark* elem) {
|
||||
oop obj = elem->get_oop();
|
||||
if (obj->is_forwarded()) {
|
||||
elem->set_oop(obj->forwardee());
|
||||
}
|
||||
}
|
||||
|
||||
oop obj = elem->get_oop();
|
||||
if (obj->is_forwarded()) {
|
||||
elem->set_oop(obj->forwardee());
|
||||
}
|
||||
void PreservedMarks::adjust_during_full_gc() {
|
||||
StackIterator<PreservedMark, mtGC> iter(_stack);
|
||||
while (!iter.is_empty()) {
|
||||
PreservedMark* elem = iter.next_addr();
|
||||
adjust_preserved_mark(elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,23 +34,24 @@ class WorkerTask;
|
||||
class PreservedMarksSet;
|
||||
class WorkerThreads;
|
||||
|
||||
class PreservedMark {
|
||||
private:
|
||||
oop _o;
|
||||
markWord _m;
|
||||
|
||||
public:
|
||||
PreservedMark(oop obj, markWord m) : _o(obj), _m(m) { }
|
||||
|
||||
oop get_oop() { return _o; }
|
||||
inline void set_mark() const;
|
||||
void set_oop(oop obj) { _o = obj; }
|
||||
};
|
||||
|
||||
class PreservedMarks {
|
||||
private:
|
||||
class OopAndMarkWord {
|
||||
private:
|
||||
oop _o;
|
||||
markWord _m;
|
||||
typedef Stack<PreservedMark, mtGC> PreservedMarkStack;
|
||||
|
||||
public:
|
||||
OopAndMarkWord(oop obj, markWord m) : _o(obj), _m(m) { }
|
||||
|
||||
oop get_oop() { return _o; }
|
||||
inline void set_mark() const;
|
||||
void set_oop(oop obj) { _o = obj; }
|
||||
};
|
||||
typedef Stack<OopAndMarkWord, mtGC> OopAndMarkWordStack;
|
||||
|
||||
OopAndMarkWordStack _stack;
|
||||
PreservedMarkStack _stack;
|
||||
|
||||
inline bool should_preserve_mark(oop obj, markWord m) const;
|
||||
|
||||
@ -61,6 +62,11 @@ public:
|
||||
// Iterate over the stack, restore all preserved marks, and
|
||||
// reclaim the memory taken up by the stack segments.
|
||||
void restore();
|
||||
|
||||
// Adjust the preserved mark according to its
|
||||
// forwarding location stored in the mark.
|
||||
static void adjust_preserved_mark(PreservedMark* elem);
|
||||
|
||||
// Iterate over the stack, adjust all preserved marks according
|
||||
// to their forwarding location stored in the mark.
|
||||
void adjust_during_full_gc();
|
||||
|
||||
@ -37,26 +37,26 @@ inline bool PreservedMarks::should_preserve_mark(oop obj, markWord m) const {
|
||||
|
||||
inline void PreservedMarks::push_if_necessary(oop obj, markWord m) {
|
||||
if (should_preserve_mark(obj, m)) {
|
||||
OopAndMarkWord elem(obj, m);
|
||||
PreservedMark elem(obj, m);
|
||||
_stack.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
inline void PreservedMarks::push_always(oop obj, markWord m) {
|
||||
assert(!m.is_marked(), "precondition");
|
||||
OopAndMarkWord elem(obj, m);
|
||||
PreservedMark elem(obj, m);
|
||||
_stack.push(elem);
|
||||
}
|
||||
|
||||
inline PreservedMarks::PreservedMarks()
|
||||
: _stack(OopAndMarkWordStack::default_segment_size(),
|
||||
: _stack(PreservedMarkStack::default_segment_size(),
|
||||
// This stack should be used very infrequently so there's
|
||||
// no point in caching stack segments (there will be a
|
||||
// waste of space most of the time). So we set the max
|
||||
// cache size to 0.
|
||||
0 /* max_cache_size */) { }
|
||||
|
||||
void PreservedMarks::OopAndMarkWord::set_mark() const {
|
||||
void PreservedMark::set_mark() const {
|
||||
_o->set_mark(_m);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user