加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
support_jmap_parallel_inspection_for_cms_gc.patch 7.20 KB
一键复制 编辑 原始数据 按行查看 历史
kuen 提交于 2022-02-08 17:37 . I4SV7X: upgrade to jdk11.0.14-ga
diff --git a/src/hotspot/share/gc/cms/cmsHeap.cpp b/src/hotspot/share/gc/cms/cmsHeap.cpp
index 2c70eb375..880c1db03 100644
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp
@@ -264,3 +264,66 @@ GrowableArray<MemoryPool*> CMSHeap::memory_pools() {
memory_pools.append(_old_pool);
return memory_pools;
}
+
+// The CMSHeapBlockClaimer is used during parallel iteration over the heap,
+// allowing workers to claim heap areas ("blocks"), gaining exclusive rights to these.
+// The eden and survivor spaces are treated as single blocks as it is hard to divide
+// these spaces.
+// The old space is divided into fixed-size blocks.
+class CMSHeapBlockClaimer : public StackObj {
+ size_t _claimed_index;
+
+public:
+ static const size_t InvalidIndex = SIZE_MAX;
+ static const size_t EdenIndex = 0;
+ static const size_t SurvivorIndex = 1;
+ static const size_t NumNonOldGenClaims = 2;
+
+ CMSHeapBlockClaimer() : _claimed_index(EdenIndex) { }
+ // Claim the block and get the block index.
+ size_t claim_and_get_block()
+ {
+ size_t block_index;
+ block_index = Atomic::add(1u, &_claimed_index) - 1;
+ size_t num_claims = CMSHeap::heap()->old_gen()->num_iterable_blocks() + NumNonOldGenClaims;
+ return block_index < num_claims ? block_index : InvalidIndex;
+ }
+};
+
+void CMSHeap::object_iterate_parallel(ObjectClosure *cl, CMSHeapBlockClaimer *claimer)
+{
+ size_t block_index = claimer->claim_and_get_block();
+ // Iterate until all blocks are claimed
+ if (block_index == CMSHeapBlockClaimer::EdenIndex) {
+ young_gen()->eden()->object_iterate(cl);
+ block_index = claimer->claim_and_get_block();
+ }
+ if (block_index == CMSHeapBlockClaimer::SurvivorIndex) {
+ young_gen()->from()->object_iterate(cl);
+ young_gen()->to()->object_iterate(cl);
+ block_index = claimer->claim_and_get_block();
+ }
+ while (block_index != CMSHeapBlockClaimer::InvalidIndex) {
+ old_gen()->object_iterate_block(cl, block_index - CMSHeapBlockClaimer::NumNonOldGenClaims);
+ block_index = claimer->claim_and_get_block();
+ }
+}
+
+class CMSParallelObjectIterator : public ParallelObjectIterator {
+private:
+ CMSHeap *_heap;
+ CMSHeapBlockClaimer _claimer;
+
+public:
+ CMSParallelObjectIterator(uint thread_num) : _heap(CMSHeap::heap()), _claimer(){}
+
+ virtual void object_iterate(ObjectClosure *cl, uint worker_id)
+ {
+ _heap->object_iterate_parallel(cl, &_claimer);
+ }
+};
+
+ParallelObjectIterator* CMSHeap::parallel_object_iterator(uint thread_num)
+{
+ return new CMSParallelObjectIterator(thread_num);
+}
diff --git a/src/hotspot/share/gc/cms/cmsHeap.hpp b/src/hotspot/share/gc/cms/cmsHeap.hpp
index 93f177aad..e02a10c59 100644
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp
@@ -34,6 +34,7 @@
#include "utilities/growableArray.hpp"
class CLDClosure;
+class CMSHeapBlockClaimer;
class GenCollectorPolicy;
class GCMemoryManager;
class MemoryPool;
@@ -106,6 +107,14 @@ public:
return static_cast<ConcurrentMarkSweepGeneration*>(_old_gen);
}
+ virtual ParallelObjectIterator* parallel_object_iterator(uint thread_num);
+ // Iteration functions.
+ void object_iterate_parallel(ObjectClosure *cl, CMSHeapBlockClaimer *claimer);
+ virtual WorkGang* get_safepoint_workers()
+ {
+ return workers();
+ }
+
// Apply "cur->do_oop" or "older->do_oop" to all the oops in objects
// allocated since the last call to save_marks in the young generation.
// The "cur" closure is applied to references in the younger generation
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
index 708e92c53..2ebbd638e 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
@@ -2733,6 +2733,46 @@ void ConcurrentMarkSweepGeneration::shrink_free_list_by(size_t bytes) {
return;
}
+size_t ConcurrentMarkSweepGeneration::num_iterable_blocks() const
+{
+ return (used_stable() + CMSIterateBlockSize - 1) / CMSIterateBlockSize;
+}
+
+void ConcurrentMarkSweepGeneration::object_iterate_block(ObjectClosure *cl, size_t block_index)
+{
+ size_t block_word_size = CMSIterateBlockSize / HeapWordSize;
+ MemRegion span = MemRegion(cmsSpace()->bottom() + block_index * block_word_size,
+ cmsSpace()->bottom() + (block_index + 1) * block_word_size);
+ if (!span.is_empty()) { // Non-null task
+ HeapWord *prev_obj;
+ if (block_index == 0) {
+ prev_obj = span.start();
+ } else {
+ prev_obj = cmsSpace()->block_start_careful(span.start());
+ while (prev_obj < span.start()) {
+ size_t sz = cmsSpace()->block_size_no_stall(prev_obj, _collector);
+ if (sz > 0) {
+ prev_obj += sz;
+ } else {
+ break;
+ }
+ }
+ }
+ if (prev_obj < span.end()) {
+ HeapWord *cur, *limit;
+ size_t curSize;
+ for (cur = prev_obj, limit =span.end(); cur < limit; cur += curSize) {
+ curSize = cmsSpace()->block_size_no_stall(cur, _collector);
+ if (curSize == 0) {
+ break;
+ }
+ if (cmsSpace()->block_is_obj(cur)) {
+ cl->do_object(oop(cur));
+ }
+ }
+ }
+ }
+}
// Simple ctor/dtor wrapper for accounting & timer chores around concurrent
// phases.
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
index 4f272394b..9e93fefac 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp
@@ -1010,6 +1010,9 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
// Words directly allocated, used by CMSStats.
size_t _direct_allocated_words;
+ //CMS Parallel iterate block size
+ static const size_t CMSIterateBlockSize = 1024 * 1024;
+
// Non-product stat counters
NOT_PRODUCT(
size_t _numObjectsPromoted;
@@ -1091,6 +1094,9 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
void set_did_compact(bool v) { _did_compact = v; }
+ virtual size_t num_iterable_blocks() const;
+ virtual void object_iterate_block(ObjectClosure *cl, size_t block_index);
+
bool refs_discovery_is_atomic() const { return false; }
bool refs_discovery_is_mt() const {
// Note: CMS does MT-discovery during the parallel-remark
diff --git a/test/jdk/sun/tools/jmap/BasicJMapTest.java b/test/jdk/sun/tools/jmap/BasicJMapTest.java
index 327feb25d..ad890f880 100644
--- a/test/jdk/sun/tools/jmap/BasicJMapTest.java
+++ b/test/jdk/sun/tools/jmap/BasicJMapTest.java
@@ -45,6 +45,21 @@ import jdk.testlibrary.ProcessTools;
* @build jdk.test.lib.hprof.util.*
* @run main/timeout=240 BasicJMapTest
*/
+
+/*
+ * @test id=CMS
+ * @summary Unit test for jmap utility (CMS GC)
+ * @key intermittent
+ * @library /lib/testlibrary
+ * @library /test/lib
+ * @build jdk.testlibrary.*
+ * @build jdk.test.lib.hprof.*
+ * @build jdk.test.lib.hprof.model.*
+ * @build jdk.test.lib.hprof.parser.*
+ * @build jdk.test.lib.hprof.util.*
+ * @run main/othervm/timeout=240 -XX:+UseConcMarkSweepGC BasicJMapTest
+ */
+
public class BasicJMapTest {
private static ProcessBuilder processBuilder = new ProcessBuilder();
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化