< prev index next >
src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.inline.hpp
Print this page
rev 10493 : [Backport] Shenandoah string deduplication
rev 10496 : [backport] Rename "cancel_concgc" to "cancel_gc"
rev 10504 : [backport] Full GC always comes with liveness data
rev 10531 : [backport] Improve scheduling and interleaving of SATB processing in mark loop
rev 10537 : [backport] Skip RESOLVE in SATBBufferClosure if no forwarded objects are in heap
rev 10580 : [backport] Refactor to group marking bitmap and TAMS structure in one class ShenandoahMarkingContext
rev 10582 : [backport] Avoid indirection to next-mark-context
*** 26,51 ****
#include "gc_implementation/shenandoah/brooksPointer.hpp"
#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp"
#include "gc_implementation/shenandoah/shenandoahConcurrentMark.hpp"
#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
#include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/prefetch.inline.hpp"
! template <class T, bool COUNT_LIVENESS>
void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) {
oop obj = task->obj();
shenandoah_assert_not_forwarded(NULL, obj);
shenandoah_assert_marked_next(NULL, obj);
! shenandoah_assert_not_in_cset_except(NULL, obj, _heap->cancelled_concgc());
if (task->is_not_chunked()) {
! if (COUNT_LIVENESS) count_liveness(live_data, obj);
if (obj->is_instance()) {
// Case 1: Normal oop, process as usual.
obj->oop_iterate(cl);
} else if (obj->is_objArray()) {
// Case 2: Object array instance and no chunk is set. Must be the first
--- 26,53 ----
#include "gc_implementation/shenandoah/brooksPointer.hpp"
#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
#include "gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp"
#include "gc_implementation/shenandoah/shenandoahConcurrentMark.hpp"
+ #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp"
#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
+ #include "gc_implementation/shenandoah/shenandoahStringDedup.hpp"
#include "gc_implementation/shenandoah/shenandoahTaskqueue.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/prefetch.inline.hpp"
! template <class T>
void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, jushort* live_data, ShenandoahMarkTask* task) {
oop obj = task->obj();
shenandoah_assert_not_forwarded(NULL, obj);
shenandoah_assert_marked_next(NULL, obj);
! shenandoah_assert_not_in_cset_except(NULL, obj, _heap->cancelled_gc());
if (task->is_not_chunked()) {
! count_liveness(live_data, obj);
if (obj->is_instance()) {
// Case 1: Normal oop, process as usual.
obj->oop_iterate(cl);
} else if (obj->is_objArray()) {
// Case 2: Object array instance and no chunk is set. Must be the first
*** 204,236 ****
class ShenandoahSATBBufferClosure : public SATBBufferClosure {
private:
ShenandoahObjToScanQueue* _queue;
ShenandoahHeap* _heap;
public:
ShenandoahSATBBufferClosure(ShenandoahObjToScanQueue* q) :
! _queue(q), _heap(ShenandoahHeap::heap())
{
}
! void do_buffer(void** buffer, size_t size) {
for (size_t i = 0; i < size; ++i) {
! oop* p = (oop*) &buffer[i];
! ShenandoahConcurrentMark::mark_through_ref<oop, RESOLVE>(p, _heap, _queue);
}
}
};
! inline bool ShenandoahConcurrentMark::try_draining_satb_buffer(ShenandoahObjToScanQueue *q, ShenandoahMarkTask &task) {
! ShenandoahSATBBufferClosure cl(q);
! SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
! bool had_refs = satb_mq_set.apply_closure_to_completed_buffer(&cl);
! return had_refs && try_queue(q, task);
}
! template<class T, UpdateRefsMode UPDATE_REFS>
! inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q) {
T o = oopDesc::load_heap_oop(p);
if (! oopDesc::is_null(o)) {
oop obj = oopDesc::decode_heap_oop_not_null(o);
switch (UPDATE_REFS) {
case NONE:
--- 206,248 ----
class ShenandoahSATBBufferClosure : public SATBBufferClosure {
private:
ShenandoahObjToScanQueue* _queue;
ShenandoahHeap* _heap;
+ ShenandoahMarkingContext* const _mark_context;
public:
ShenandoahSATBBufferClosure(ShenandoahObjToScanQueue* q) :
! _queue(q),
! _heap(ShenandoahHeap::heap()),
! _mark_context(_heap->next_marking_context())
{
}
! void do_buffer(void **buffer, size_t size) {
! if (_heap->has_forwarded_objects()) {
! do_buffer_impl<RESOLVE>(buffer, size);
! } else {
! do_buffer_impl<NONE>(buffer, size);
! }
! }
!
! template<UpdateRefsMode UPDATE_REFS>
! void do_buffer_impl(void **buffer, size_t size) {
for (size_t i = 0; i < size; ++i) {
! oop *p = (oop *) &buffer[i];
! ShenandoahConcurrentMark::mark_through_ref<oop, UPDATE_REFS>(p, _heap, _queue, _mark_context);
}
}
};
! template<class T, UpdateRefsMode UPDATE_REFS>
! inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context) {
! ShenandoahConcurrentMark::mark_through_ref<T, UPDATE_REFS, false /* string dedup */>(p, heap, q, mark_context, NULL);
}
! template<class T, UpdateRefsMode UPDATE_REFS, bool STRING_DEDUP>
! inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, ShenandoahStrDedupQueue* dq) {
T o = oopDesc::load_heap_oop(p);
if (! oopDesc::is_null(o)) {
oop obj = oopDesc::decode_heap_oop_not_null(o);
switch (UPDATE_REFS) {
case NONE:
*** 252,266 ****
// Note: Only when concurrently updating references can obj become NULL here.
// It happens when a mutator thread beats us by writing another value. In that
// case we don't need to do anything else.
if (UPDATE_REFS != CONCURRENT || !oopDesc::is_null(obj)) {
shenandoah_assert_not_forwarded(p, obj);
! shenandoah_assert_not_in_cset_except(p, obj, heap->cancelled_concgc());
! if (heap->mark_next(obj)) {
bool pushed = q->push(ShenandoahMarkTask(obj));
assert(pushed, "overflow queue should always succeed pushing");
}
shenandoah_assert_marked_next(p, obj);
}
}
--- 264,284 ----
// Note: Only when concurrently updating references can obj become NULL here.
// It happens when a mutator thread beats us by writing another value. In that
// case we don't need to do anything else.
if (UPDATE_REFS != CONCURRENT || !oopDesc::is_null(obj)) {
shenandoah_assert_not_forwarded(p, obj);
! shenandoah_assert_not_in_cset_except(p, obj, heap->cancelled_gc());
! if (mark_context->mark(obj)) {
bool pushed = q->push(ShenandoahMarkTask(obj));
assert(pushed, "overflow queue should always succeed pushing");
+
+ if (STRING_DEDUP && ShenandoahStringDedup::is_candidate(obj)) {
+ assert(ShenandoahStringDedup::is_enabled(), "Must be enabled");
+ assert(dq != NULL, "Dedup queue not set");
+ ShenandoahStringDedup::enqueue_candidate(obj, dq);
+ }
}
shenandoah_assert_marked_next(p, obj);
}
}
< prev index next >