From fb0df4e294eb286156fb97a6ce206f3d18f5dc10 Mon Sep 17 00:00:00 2001 From: yoa1226 Date: Thu, 24 Oct 2024 13:23:24 +0800 Subject: [PATCH] conc mark scan region root2 --- ...024-09-15-g1-conc-mark-root-region-scan.md | 113 ++++++++++++++++++ .../conc-root-region-scan-bitmap-mark.png | Bin 0 -> 35231 bytes 2 files changed, 113 insertions(+) create mode 100644 assets/conc-root-region-scan/conc-root-region-scan-bitmap-mark.png diff --git a/_posts/2024-09-15-g1-conc-mark-root-region-scan.md b/_posts/2024-09-15-g1-conc-mark-root-region-scan.md index db5d751..70dd7c8 100644 --- a/_posts/2024-09-15-g1-conc-mark-root-region-scan.md +++ b/_posts/2024-09-15-g1-conc-mark-root-region-scan.md @@ -381,9 +381,122 @@ void G1CMRootMemRegions::add(HeapWord* start, HeapWord* end) { ## root region scan +root region scan 的最终遍历是在 `G1ConcurrentMark::scan_root_region(...)` 完成的。 +`region->start()` 是 TAMS 的位置,`region->end()` 是 top 所在位置。 +`root_regions->claim_next()` 负责对线程进行同步。 +```cpp +void G1ConcurrentMark::scan_root_regions() { + G1CMRootRegionScanTask task(this); + _concurrent_workers->run_task(&task, num_workers); +} + +class G1CMRootRegionScanTask : public WorkerTask { + void work(uint worker_id) { + G1CMRootMemRegions* root_regions = _cm->root_regions(); + const MemRegion* region = root_regions->claim_next(); + while (region != nullptr) { + _cm->scan_root_region(region, worker_id); + region = root_regions->claim_next(); + } } +} + +void G1ConcurrentMark::scan_root_region(const MemRegion* region, uint worker_id) { + G1RootRegionScanClosure cl(_g1h, this, worker_id); + HeapWord* curr = region->start(); + const HeapWord* end = region->end(); + while (curr < end) { + Prefetch::read(curr, interval); + oop obj = cast_to_oop(curr); + size_t size = obj->oop_iterate_size(&cl); + curr += size; + } +} +``` + +注意上面的代码并没有对 `obj->oop_iterate_size(&cl)` 中 `obj` 对象本身进行标记,这是由于 root region 作为 gc root object 一定是存活的对象,此类对象不需要被标记。 + +`G1RootRegionScanClosure::do_oop_work` 方法标记对象,此对象为上述对象引用类型的属性。 + +```cpp +inline void G1RootRegionScanClosure::do_oop_work(T* p) { + T heap_oop = RawAccess::oop_load(p); + if (CompressedOops::is_null(heap_oop)) { + return; + } + oop obj = CompressedOops::decode_not_null(heap_oop); + _cm->mark_in_bitmap(_worker_id, obj); +} +``` + +### mark_bitmap + +在并发标记中使用使用 bitmap 标记存活的对象,使用一个 bit 标记 64 bit 也就是 8 bytes。在 32 位操作系统中,8 bytes 恰好是最小对象所占字节(markword + class pointer)。 + + + +### set bit + +下面看看 G1 是如果将对象地址映射到 mark_bitmap 上去的,又是如何标记对应 bit 的。 + +`pointer_delta(addr, _covered.start()) >> _shifter` 计算的是 `addr` 在 mark_bitmap 中的相对位置。 + +比如图中紫色对象对应的相对位置的索引是 4。 + +```cpp +inline bool MarkBitMap::par_mark(HeapWord* addr) { + check_mark(addr); + return _bm.par_set_bit(addr_to_offset(addr)); +} + +size_t addr_to_offset(const HeapWord* addr) const { + return pointer_delta(addr, _covered.start()) >> _shifter; +} + +inline bool BitMap::par_set_bit(idx_t bit, atomic_memory_order memory_order) { + verify_index(bit); + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = bit_mask(bit); + bm_word_t old_val = load_word_ordered(addr, memory_order); +} +``` + +`word_addr` 获取 bit 位置在 mark_bitmap 上的所归属的地址,然后使用 `load_word_ordered` 将地址的所在的读出来,并且一次性读 64 bit ,即 8 个字节。 + +`bit_in_word` 将地址在 mark_bitmap 上偏移映射到 64 bit 上,例如 bit = 76,那么 bit 在第二个 64 bit 上的偏移为 12(76 / 64)(最小为0)。 + +`1 << bit_in_word(bit)` 等于 `1000000000000`,标记第 13 个bit 为 1,表示这个位置的对象状态为存活。 + +```cpp +bm_word_t* word_addr(idx_t bit) { + return map() + to_words_align_down(bit); +} + +static idx_t bit_in_word(idx_t bit) { return bit & (BitsPerWord - 1); } + +static bm_word_t bit_mask(idx_t bit) { return (bm_word_t)1 << bit_in_word(bit); } +``` + +`new_val = old_val | mask` 与旧值相或得到新值,`Atomic::cmpxchg` 设置新值,此地址所在的对象标记完成。 + +mark_bitmap 占整个堆空间的 1/64(1.56%)。 + +```cpp +do { + const bm_word_t new_val = old_val | mask; + if (new_val == old_val) { + return false; // Someone else beat us to it. + } + const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order); + if (cur_val == old_val) { + return true; // Success. + } + old_val = cur_val; // The value changed, try again. +} while (true); +``` +本文介绍了并发标记触发的条件、TAMS的概念、root region 的组成、mark_bitmap 的结构和标记原理。 diff --git a/assets/conc-root-region-scan/conc-root-region-scan-bitmap-mark.png b/assets/conc-root-region-scan/conc-root-region-scan-bitmap-mark.png new file mode 100644 index 0000000000000000000000000000000000000000..3eed68fb2cbaba90e1d98a1ee528192fd6b74a51 GIT binary patch literal 35231 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