Skip to content
Permalink
Browse files
8215624: Add parallel heap iteration for jmap –histo
8253763: ParallelObjectIterator should have virtual destructor

Chunk and parallelize the heap scan

Reviewed-by: clanger
Backport-of: 3498a10
  • Loading branch information
buddyliao authored and RealCLanger committed Sep 8, 2021
1 parent 2de01c1 commit 085dbe326db0684bee22719094ff7e719f9aacb0
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@@ -67,6 +67,9 @@ class CMSHeap : public GenCollectedHeap {

virtual void print_gc_threads_on(outputStream* st) const;
virtual void gc_threads_do(ThreadClosure* tc) const;
// Runs the given AbstractGangTask with the current active workers.
// No workGang for CmsHeap, work serially with thread 0
virtual void run_task(AbstractGangTask* task) { task->work(0); }
virtual void print_on_error(outputStream* st) const;

// Perform a full collection of the heap; intended for use in implementing
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
* Copyright (c) 2017, 2021, Red Hat, Inc. 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
@@ -136,6 +136,10 @@ class EpsilonHeap : public CollectedHeap {
virtual void print_gc_threads_on(outputStream* st) const {}
virtual void gc_threads_do(ThreadClosure* tc) const {}

// Runs the given AbstractGangTask with the current active workers
// No workGang for EpsilonHeap, work serially with thread 0
virtual void run_task(AbstractGangTask* task) { task->work(0); }

// No heap verification
virtual void prepare_for_verify() {}
virtual void verify(VerifyOption option) {}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@@ -78,6 +78,7 @@
#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
#include "memory/heapInspection.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
@@ -152,6 +153,9 @@ void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_region
reset_from_card_cache(start_idx, num_regions);
}

void G1CollectedHeap::run_task(AbstractGangTask* task) {
workers()->run_task(task, workers()->active_workers());
}

HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
MemRegion mr) {
@@ -2120,6 +2124,30 @@ void G1CollectedHeap::object_iterate(ObjectClosure* cl) {
heap_region_iterate(&blk);
}

class G1ParallelObjectIterator : public ParallelObjectIterator {
private:
G1CollectedHeap* _heap;
HeapRegionClaimer _claimer;

public:
G1ParallelObjectIterator(uint thread_num) :
_heap(G1CollectedHeap::heap()),
_claimer(thread_num == 0 ? G1CollectedHeap::heap()->workers()->active_workers() : thread_num) {}

virtual void object_iterate(ObjectClosure* cl, uint worker_id) {
_heap->object_iterate_parallel(cl, worker_id, &_claimer);
}
};

ParallelObjectIterator* G1CollectedHeap::parallel_object_iterator(uint thread_num) {
return new G1ParallelObjectIterator(thread_num);
}

void G1CollectedHeap::object_iterate_parallel(ObjectClosure* cl, uint worker_id, HeapRegionClaimer* claimer) {
IterateObjectClosureRegionClosure blk(cl);
heap_region_par_iterate_from_worker_offset(&blk, claimer, worker_id);
}

void G1CollectedHeap::keep_alive(oop obj) {
G1BarrierSet::enqueue(obj);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@@ -528,6 +528,9 @@ class G1CollectedHeap : public CollectedHeap {

WorkGang* workers() const { return _workers; }

// Runs the given AbstractGangTask with the current active workers.
virtual void run_task(AbstractGangTask* task);

G1Allocator* allocator() {
return _allocator;
}
@@ -1116,13 +1119,17 @@ class G1CollectedHeap : public CollectedHeap {

// Iteration functions.

void object_iterate_parallel(ObjectClosure* cl, uint worker_id, HeapRegionClaimer* claimer);

// Iterate over all objects, calling "cl.do_object" on each.
virtual void object_iterate(ObjectClosure* cl);

virtual void safe_object_iterate(ObjectClosure* cl) {
object_iterate(cl);
}

virtual ParallelObjectIterator* parallel_object_iterator(uint thread_num);

// Keep alive an object that was loaded with AS_NO_KEEPALIVE.
virtual void keep_alive(oop obj);

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@@ -604,6 +604,12 @@ void ParallelScavengeHeap::print_gc_threads_on(outputStream* st) const {
PSScavenge::gc_task_manager()->print_threads_on(st);
}

void ParallelScavengeHeap::run_task(AbstractGangTask* task) {
WorkGang workers("GC Threads", ParallelGCThreads, true, false);
workers.initialize_workers();
workers.run_task(task);
}

void ParallelScavengeHeap::print_tracing_info() const {
AdaptiveSizePolicyOutput::print();
log_debug(gc, heap, exit)("Accumulated young generation GC time %3.7f secs", PSScavenge::accumulated_time()->seconds());
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@@ -49,6 +49,7 @@ class MemoryPool;
class PSAdaptiveSizePolicy;
class PSCardTable;
class PSHeapSummary;
class WorkGang;

class ParallelScavengeHeap : public CollectedHeap {
friend class VMStructs;
@@ -230,6 +231,8 @@ class ParallelScavengeHeap : public CollectedHeap {
virtual void print_on_error(outputStream* st) const;
virtual void print_gc_threads_on(outputStream* st) const;
virtual void gc_threads_do(ThreadClosure* tc) const;
// Runs the given AbstractGangTask with the current active workers.
virtual void run_task(AbstractGangTask* task);
virtual void print_tracing_info() const;

void verify(VerifyOption option /* ignored */);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@@ -81,6 +81,10 @@ class SerialHeap : public GenCollectedHeap {
template <typename OopClosureType1, typename OopClosureType2>
void oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older);

// Runs the given AbstractGangTask with the current active workers.
// No workGang for SerialHeap, work serially with thread 0.
virtual void run_task(AbstractGangTask* task) { task->work(0); }
};

#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@@ -28,6 +28,7 @@
#include "gc/shared/gcCause.hpp"
#include "gc/shared/gcWhen.hpp"
#include "memory/allocation.hpp"
#include "memory/heapInspection.hpp"
#include "runtime/handles.hpp"
#include "runtime/perfData.hpp"
#include "runtime/safepoint.hpp"
@@ -42,6 +43,7 @@
// class defines the functions that a heap must implement, and contains
// infrastructure common to all heaps.

class AbstractGangTask;
class AdaptiveSizePolicy;
class BarrierSet;
class CollectorPolicy;
@@ -83,6 +85,12 @@ class GCHeapLog : public EventLogBase<GCMessage> {
}
};

class ParallelObjectIterator : public CHeapObj<mtGC> {
public:
virtual void object_iterate(ObjectClosure* cl, uint worker_id) = 0;
virtual ~ParallelObjectIterator() {}
};

//
// CollectedHeap
// GenCollectedHeap
@@ -465,6 +473,10 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// the block is an object.
virtual bool block_is_obj(const HeapWord* addr) const = 0;

virtual ParallelObjectIterator* parallel_object_iterator(uint thread_num) {
return NULL;
}

// Keep alive an object that was loaded with AS_NO_KEEPALIVE.
virtual void keep_alive(oop obj) {}

@@ -516,6 +528,9 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// Iterator for all GC threads (other than VM thread)
virtual void gc_threads_do(ThreadClosure* tc) const = 0;

// Run given task. Possibly in parallel if the GC supports it.
virtual void run_task(AbstractGangTask* task) = 0;

// Print any relevant tracing info that flags imply.
// Default implementation does nothing.
virtual void print_tracing_info() const = 0;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, 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
@@ -154,7 +154,7 @@ void VM_GC_HeapInspection::doit() {
}
HeapInspection inspect(_csv_format, _print_help, _print_class_stats,
_columns);
inspect.heap_inspection(_out);
inspect.heap_inspection(_out, _parallel_thread_num);
}


@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, 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
@@ -125,18 +125,21 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
private:
outputStream* _out;
bool _full_gc;
uint _parallel_thread_num;
bool _csv_format; // "comma separated values" format for spreadsheet.
bool _print_help;
bool _print_class_stats;
const char* _columns;
public:
VM_GC_HeapInspection(outputStream* out, bool request_full_gc) :
VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
uint parallel_thread_num = 1) :
VM_GC_Operation(0 /* total collections, dummy, ignored */,
GCCause::_heap_inspection /* GC Cause */,
0 /* total full collections, dummy, ignored */,
request_full_gc) {
_out = out;
_full_gc = request_full_gc;
_parallel_thread_num = parallel_thread_num;
_csv_format = false;
_print_help = false;
_print_class_stats = false;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved.
* Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved.
*
* 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
@@ -206,6 +206,10 @@ class ShenandoahHeap : public CollectedHeap {

void gc_threads_do(ThreadClosure* tcl) const;

// Runs the given AbstractGangTask with the current active workers
// No workGang for shenandoahHeap, work serially with thread 0
virtual void run_task(AbstractGangTask* task) { task->work(0); }

// ---------- Heap regions handling machinery
//
private:
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
@@ -103,6 +103,10 @@ class ZCollectedHeap : public CollectedHeap {
virtual void object_iterate(ObjectClosure* cl);
virtual void safe_object_iterate(ObjectClosure* cl);

// Runs the given AbstractGangTask with the current active workers.
// No workGang for zHeap, work serially with thread 0
virtual void run_task(AbstractGangTask* task) { task->work(0); }

virtual HeapWord* block_start(const void* addr) const;
virtual size_t block_size(const HeapWord* addr) const;
virtual bool block_is_obj(const HeapWord* addr) const;

1 comment on commit 085dbe3

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 085dbe3 Sep 8, 2021

Please sign in to comment.