1 | /* |
2 | * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_GC_G1_HETEROGENEOUSHEAPREGIONMANAGER_HPP |
26 | #define SHARE_GC_G1_HETEROGENEOUSHEAPREGIONMANAGER_HPP |
27 | |
28 | #include "gc/g1/heapRegionManager.hpp" |
29 | |
30 | // This class manages heap regions on heterogenous memory comprising of dram and nv-dimm. |
31 | // Regions in dram (dram_set) are used for young objects and archive regions (CDS). |
32 | // Regions in nv-dimm (nvdimm_set) are used for old objects and humongous objects. |
33 | // At any point there are some regions committed on dram and some on nv-dimm with the following guarantees: |
34 | // 1. The total number of regions committed in dram and nv-dimm equals the current size of heap. |
35 | // 2. Consequently, total number of regions committed is less than or equal to Xmx. |
36 | // 3. To maintain the guarantee stated by 1., whenever one set grows (new regions committed), the other set shrinks (regions un-committed). |
37 | // 3a. If more dram regions are needed (young generation expansion), corresponding number of regions in nv-dimm are un-committed. |
38 | // 3b. When old generation or humongous set grows, and new regions need to be committed to nv-dimm, corresponding number of regions |
39 | // are un-committed in dram. |
40 | class HeterogeneousHeapRegionManager : public HeapRegionManager { |
41 | const uint _max_regions; |
42 | uint _max_dram_regions; |
43 | uint _max_nvdimm_regions; |
44 | uint _start_index_of_nvdimm; |
45 | uint _total_commited_before_full_gc; |
46 | uint _no_borrowed_regions; |
47 | |
48 | uint total_regions_committed() const; |
49 | uint num_committed_dram() const; |
50 | uint num_committed_nvdimm() const; |
51 | |
52 | // Similar to find_unavailable_from_idx() function from base class, difference is this function searches in range [start, end]. |
53 | uint find_unavailable_in_range(uint start_idx, uint end_idx, uint* res_idx) const; |
54 | |
55 | // Expand into dram. Maintains the invariant that total number of committed regions is less than current heap size. |
56 | uint expand_dram(uint num_regions, WorkGang* pretouch_workers); |
57 | |
58 | // Expand into nv-dimm. |
59 | uint expand_nvdimm(uint num_regions, WorkGang* pretouch_workers); |
60 | |
61 | // Expand by finding unavailable regions in [start, end] range. |
62 | uint expand_in_range(uint start, uint end, uint num_regions, WorkGang* pretouch_workers); |
63 | |
64 | // Shrink dram set of regions. |
65 | uint shrink_dram(uint num_regions, bool update_free_list = true); |
66 | |
67 | // Shrink nv-dimm set of regions. |
68 | uint shrink_nvdimm(uint num_regions, bool update_free_list = true); |
69 | |
70 | // Shrink regions from [start, end] range. |
71 | uint shrink_in_range(uint start, uint end, uint num_regions, bool update_free_list = true); |
72 | |
73 | // Similar to find_empty_from_idx_reverse() in base class. Only here it searches in a range. |
74 | uint find_empty_in_range_reverse(uint start_idx, uint end_idx, uint* res_idx); |
75 | |
76 | // Similar to find_contiguous() in base class, with [start, end] range |
77 | uint find_contiguous(size_t start, size_t end, size_t num, bool empty_only); |
78 | |
79 | // This function is called when there are no free nv-dimm regions. |
80 | // It borrows a region from the set of unavailable regions in nv-dimm for GC purpose. |
81 | HeapRegion* borrow_old_region_for_gc(); |
82 | |
83 | uint free_list_dram_length() const; |
84 | uint free_list_nvdimm_length() const; |
85 | |
86 | // is region with given index in nv-dimm? |
87 | bool is_in_nvdimm(uint index) const; |
88 | bool is_in_dram(uint index) const; |
89 | |
90 | public: |
91 | |
92 | // Empty constructor, we'll initialize it with the initialize() method. |
93 | HeterogeneousHeapRegionManager(uint num_regions) : _max_regions(num_regions), _max_dram_regions(0), |
94 | _max_nvdimm_regions(0), _start_index_of_nvdimm(0), |
95 | _total_commited_before_full_gc(0), _no_borrowed_regions(0) |
96 | {} |
97 | |
98 | static HeterogeneousHeapRegionManager* manager(); |
99 | |
100 | virtual void initialize(G1RegionToSpaceMapper* heap_storage, |
101 | G1RegionToSpaceMapper* prev_bitmap, |
102 | G1RegionToSpaceMapper* next_bitmap, |
103 | G1RegionToSpaceMapper* bot, |
104 | G1RegionToSpaceMapper* cardtable, |
105 | G1RegionToSpaceMapper* card_counts); |
106 | |
107 | uint start_index_of_nvdimm() const; |
108 | uint start_index_of_dram() const; |
109 | uint end_index_of_nvdimm() const; |
110 | uint end_index_of_dram() const; |
111 | |
112 | // Override. |
113 | HeapRegion* get_dummy_region(); |
114 | |
115 | // Adjust dram_set to provision 'expected_num_regions' regions. |
116 | void adjust_dram_regions(uint expected_num_regions, WorkGang* pretouch_workers); |
117 | |
118 | // Prepare heap regions before and after full collection. |
119 | void prepare_for_full_collection_start(); |
120 | void prepare_for_full_collection_end(); |
121 | |
122 | virtual HeapRegion* allocate_free_region(HeapRegionType type); |
123 | |
124 | // Return maximum number of regions that heap can expand to. |
125 | uint max_expandable_length() const; |
126 | |
127 | // Override. Expand in nv-dimm. |
128 | uint expand_by(uint num_regions, WorkGang* pretouch_workers); |
129 | |
130 | // Override. |
131 | uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers); |
132 | |
133 | // Override. This function is called for humongous allocation, so we need to find empty regions in nv-dimm. |
134 | uint find_contiguous_only_empty(size_t num); |
135 | |
136 | // Override. This function is called for humongous allocation, so we need to find empty or unavailable regions in nv-dimm. |
137 | uint find_contiguous_empty_or_unavailable(size_t num); |
138 | |
139 | // Overrides base class implementation to find highest free region in dram. |
140 | uint find_highest_free(bool* expanded); |
141 | |
142 | // Override. This fuction is called to shrink the heap, we shrink in dram first then in nv-dimm. |
143 | uint shrink_by(uint num_regions_to_remove); |
144 | |
145 | bool has_borrowed_regions() const; |
146 | |
147 | void verify(); |
148 | }; |
149 | |
150 | #endif // SHARE_GC_G1_HETEROGENEOUSHEAPREGIONMANAGER_HPP |
151 | |