29 #include "gc/parallel/parallelScavengeHeap.hpp"
30 #include "logging/log.hpp"
31 #include "logging/logStream.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/ostream.hpp"
35
36 // Create two virtual spaces (HeteroVirtualSpaces), low() on nv-dimm memory, high() on dram.
37 // create ASPSOldGen and ASPSYoungGen the same way as in base class
38
39 AdjoiningGenerationsForHeteroHeap::AdjoiningGenerationsForHeteroHeap(ReservedSpace old_young_rs, size_t total_size_limit,
40 GenerationSizer* policy, size_t alignment) : _total_size_limit(total_size_limit) {
41 size_t init_old_byte_size = policy->initial_old_size();
42 size_t min_old_byte_size = policy->min_old_size();
43 size_t max_old_byte_size = policy->max_old_size();
44 size_t init_young_byte_size = policy->initial_young_size();
45 size_t min_young_byte_size = policy->min_young_size();
46 size_t max_young_byte_size = policy->max_young_size();
47
48 // create HeteroVirtualSpaces which is composed of non-overlapping virtual spaces.
49 _virtual_spaces = new HeteroVirtualSpaces(old_young_rs, min_old_byte_size,
50 min_young_byte_size, _total_size_limit, alignment);
51
52 assert(min_old_byte_size <= init_old_byte_size &&
53 init_old_byte_size <= max_old_byte_size, "Parameter check");
54 assert(min_young_byte_size <= init_young_byte_size &&
55 init_young_byte_size <= max_young_byte_size, "Parameter check");
56
57 assert(UseAdaptiveGCBoundary, "Should be used only when UseAdaptiveGCBoundary is true");
58
59 // Initialize the virtual spaces. Then pass a virtual space to each generation
60 // for initialization of the generation.
61
62 // Does the actual creation of the virtual spaces
63 _virtual_spaces->initialize(max_old_byte_size, init_old_byte_size, init_young_byte_size);
64
65 _young_gen = new ASPSYoungGen(_virtual_spaces->high(),
66 _virtual_spaces->high()->committed_size() /* intial_size */,
67 min_young_byte_size,
68 (static_cast <HeteroVirtualSpaces*>(_virtual_spaces))->max_young_size());
69
70 _old_gen = new ASPSOldGen(_virtual_spaces->low(),
71 _virtual_spaces->low()->committed_size() /* intial_size */,
72 min_old_byte_size,
73 (static_cast <HeteroVirtualSpaces*>(_virtual_spaces))->max_old_size(), "old", 1);
74
75 young_gen()->initialize_work();
76 assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(), "Consistency check");
77 assert(old_young_rs.size() >= young_gen()->gen_size_limit(), "Consistency check");
78
79 old_gen()->initialize_work("old", 1);
80 assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(), "Consistency check");
81 assert(old_young_rs.size() >= old_gen()->gen_size_limit(), "Consistency check");
82 }
83
84 size_t AdjoiningGenerationsForHeteroHeap::required_reserved_memory(GenerationSizer* policy) {
85 // This is the size that young gen can grow to, when AdaptiveGCBoundary is true.
86 size_t max_yg_size = policy->max_heap_byte_size() - policy->min_old_size();
87 // This is the size that old gen can grow to, when AdaptiveGCBoundary is true.
88 size_t max_old_size = policy->max_heap_byte_size() - policy->min_young_size();
89
90 return max_yg_size + max_old_size;
91 }
92
93 // We override this function since size of reservedspace here is more than heap size and
94 // callers expect this function to return heap size.
95 size_t AdjoiningGenerationsForHeteroHeap::reserved_byte_size() {
96 return total_size_limit();
97 }
98
99 AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::HeteroVirtualSpaces(ReservedSpace rs, size_t min_old_byte_size, size_t min_yg_byte_size, size_t max_total_size, size_t alignment) :
100 AdjoiningVirtualSpaces(rs, min_old_byte_size, min_yg_byte_size, alignment),
101 _min_old_byte_size(min_old_byte_size), _min_young_byte_size(min_yg_byte_size),
102 _max_old_byte_size(_max_total_size - _min_young_byte_size),
103 _max_young_byte_size(_max_total_size - _min_old_byte_size),
104 _max_total_size(max_total_size) {
105 }
106
107 void AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::initialize(size_t initial_old_reserved_size, size_t init_old_byte_size,
108 size_t init_young_byte_size) {
109
110 // This is the reserved space exclusively for old generation.
111 ReservedSpace old_rs = _reserved_space.first_part(_max_old_byte_size, true);
112 // Intially we only assign 'initial_old_reserved_size' of the reserved space to old virtual space.
113 old_rs = old_rs.first_part(initial_old_reserved_size);
114
115 // This is the reserved space exclusively for young generation.
116 ReservedSpace young_rs = _reserved_space.last_part(_max_old_byte_size).first_part(_max_young_byte_size);
117
118 // Carve out 'initial_young_reserved_size' of reserved space.
119 size_t initial_young_reserved_size = _max_total_size - initial_old_reserved_size;
120 young_rs = young_rs.last_part(_max_young_byte_size - initial_young_reserved_size);
121
122 _old_vs = new PSFileBackedVirtualSpace(old_rs, alignment(), AllocateOldGenAt);
123 if (!_old_vs->expand_by(init_old_byte_size)) {
124 vm_exit_during_initialization("Could not reserve enough space for object heap");
125 }
126
127 _young_vs = new PSVirtualSpaceHighToLow(young_rs, alignment());
128 if (!_young_vs->expand_by(init_young_byte_size)) {
129 vm_exit_during_initialization("Could not reserve enough space for object heap");
130 }
131 }
132
133 // Since the virtual spaces are non-overlapping, there is no boundary as such.
134 // We replicate the same behavior and maintain the same invariants as base class - AdjoiningVirtualSpaces, by
135 // increasing old generation size and decreasing young generation size by same amount.
136 bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_up(size_t change_in_bytes) {
137 assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
138 DEBUG_ONLY(size_t total_size_before = _young_vs->reserved_size() + _old_vs->reserved_size());
139
140 size_t bytes_needed = change_in_bytes;
141 size_t uncommitted_in_old = MIN2(_old_vs->uncommitted_size(), bytes_needed);
142 bool old_expanded = false;
143
144 // 1. Try to expand old within its reserved space.
145 if (uncommitted_in_old != 0) {
146 if (!_old_vs->expand_by(uncommitted_in_old)) {
147 return false;
148 }
149 old_expanded = true;
150 bytes_needed -= uncommitted_in_old;
151 if (bytes_needed == 0) {
152 return true;
153 }
154 }
155
156 size_t bytes_to_add_in_old = 0;
157
158 // 2. Get uncommitted memory from Young virtualspace.
159 size_t young_uncommitted = MIN2(_young_vs->uncommitted_size(), bytes_needed);
160 if (young_uncommitted > 0) {
161 _young_vs->set_reserved(_young_vs->reserved_low_addr() + young_uncommitted,
162 _young_vs->reserved_high_addr(),
163 _young_vs->special());
164 bytes_needed -= young_uncommitted;
165 bytes_to_add_in_old = young_uncommitted;
166 }
167
168 // 3. Get committed memory from Young virtualspace
169 if (bytes_needed > 0) {
170 size_t shrink_size = align_down(bytes_needed, _young_vs->alignment());
171 bool ret = _young_vs->shrink_by(shrink_size);
172 assert(ret, "We should be able to shrink young space");
173 _young_vs->set_reserved(_young_vs->reserved_low_addr() + shrink_size,
174 _young_vs->reserved_high_addr(),
175 _young_vs->special());
176
177 bytes_to_add_in_old += shrink_size;
178 }
179
180 // 4. Increase size of old space
181 _old_vs->set_reserved(_old_vs->reserved_low_addr(),
182 _old_vs->reserved_high_addr() + bytes_to_add_in_old,
183 _old_vs->special());
184 if (!_old_vs->expand_by(bytes_to_add_in_old) && !old_expanded) {
185 return false;
186 }
187
188 DEBUG_ONLY(size_t total_size_after = _young_vs->reserved_size() + _old_vs->reserved_size());
189 assert(total_size_after == total_size_before, "should be equal");
190
191 return true;
192 }
193
194 // Read comment for adjust_boundary_up()
195 // Increase young generation size and decrease old generation size by same amount.
196 bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_down(size_t change_in_bytes) {
197 assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
198 DEBUG_ONLY(size_t total_size_before = _young_vs->reserved_size() + _old_vs->reserved_size());
199
200 size_t bytes_needed = change_in_bytes;
201 size_t uncommitted_in_young = MIN2(_young_vs->uncommitted_size(), bytes_needed);
202 bool young_expanded = false;
203
204 // 1. Try to expand old within its reserved space.
205 if (uncommitted_in_young > 0) {
206 if (!_young_vs->expand_by(uncommitted_in_young)) {
207 return false;
208 }
209 young_expanded = true;
210 bytes_needed -= uncommitted_in_young;
211 if (bytes_needed == 0) {
212 return true;
213 }
214 }
215
216 size_t bytes_to_add_in_young = 0;
217
218 // 2. Get uncommitted memory from Old virtualspace.
219 size_t old_uncommitted = MIN2(_old_vs->uncommitted_size(), bytes_needed);
220 if (old_uncommitted > 0) {
221 _old_vs->set_reserved(_old_vs->reserved_low_addr(),
222 _old_vs->reserved_high_addr() - old_uncommitted,
223 _old_vs->special());
224 bytes_needed -= old_uncommitted;
225 bytes_to_add_in_young = old_uncommitted;
226 }
227
228 // 3. Get committed memory from Old virtualspace
229 if (bytes_needed > 0) {
230 size_t shrink_size = align_down(bytes_needed, _old_vs->alignment());
231 bool ret = _old_vs->shrink_by(shrink_size);
232 assert(ret, "We should be able to shrink young space");
233 _old_vs->set_reserved(_old_vs->reserved_low_addr(),
234 _old_vs->reserved_high_addr() - shrink_size,
235 _old_vs->special());
236
237 bytes_to_add_in_young += shrink_size;
238 }
239
240 assert(bytes_to_add_in_young <= change_in_bytes, "should not be more than requested size");
241 // 4. Increase size of young space
242 _young_vs->set_reserved(_young_vs->reserved_low_addr() - bytes_to_add_in_young,
243 _young_vs->reserved_high_addr(),
244 _young_vs->special());
245 if (!_young_vs->expand_by(bytes_to_add_in_young) && !young_expanded) {
246 return false;
247 }
248
249 DEBUG_ONLY(size_t total_size_after = _young_vs->reserved_size() + _old_vs->reserved_size());
250 assert(total_size_after == total_size_before, "should be equal");
251
252 return true;
253 }
254
|
29 #include "gc/parallel/parallelScavengeHeap.hpp"
30 #include "logging/log.hpp"
31 #include "logging/logStream.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/ostream.hpp"
35
36 // Create two virtual spaces (HeteroVirtualSpaces), low() on nv-dimm memory, high() on dram.
37 // create ASPSOldGen and ASPSYoungGen the same way as in base class
38
39 AdjoiningGenerationsForHeteroHeap::AdjoiningGenerationsForHeteroHeap(ReservedSpace old_young_rs, size_t total_size_limit,
40 GenerationSizer* policy, size_t alignment) : _total_size_limit(total_size_limit) {
41 size_t init_old_byte_size = policy->initial_old_size();
42 size_t min_old_byte_size = policy->min_old_size();
43 size_t max_old_byte_size = policy->max_old_size();
44 size_t init_young_byte_size = policy->initial_young_size();
45 size_t min_young_byte_size = policy->min_young_size();
46 size_t max_young_byte_size = policy->max_young_size();
47
48 // create HeteroVirtualSpaces which is composed of non-overlapping virtual spaces.
49 HeteroVirtualSpaces* hetero_virtual_spaces = new HeteroVirtualSpaces(old_young_rs, min_old_byte_size,
50 min_young_byte_size, _total_size_limit, alignment);
51
52 assert(min_old_byte_size <= init_old_byte_size &&
53 init_old_byte_size <= max_old_byte_size, "Parameter check");
54 assert(min_young_byte_size <= init_young_byte_size &&
55 init_young_byte_size <= max_young_byte_size, "Parameter check");
56
57 assert(UseAdaptiveGCBoundary, "Should be used only when UseAdaptiveGCBoundary is true");
58
59 // Initialize the virtual spaces. Then pass a virtual space to each generation
60 // for initialization of the generation.
61
62 // Does the actual creation of the virtual spaces
63 hetero_virtual_spaces->initialize(max_old_byte_size, init_old_byte_size, init_young_byte_size);
64
65 _young_gen = new ASPSYoungGen(hetero_virtual_spaces->high(),
66 hetero_virtual_spaces->high()->committed_size() /* intial_size */,
67 min_young_byte_size,
68 hetero_virtual_spaces->max_young_size());
69
70 _old_gen = new ASPSOldGen(hetero_virtual_spaces->low(),
71 hetero_virtual_spaces->low()->committed_size() /* intial_size */,
72 min_old_byte_size,
73 hetero_virtual_spaces->max_old_size(), "old", 1);
74
75 young_gen()->initialize_work();
76 assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(), "Consistency check");
77 assert(old_young_rs.size() >= young_gen()->gen_size_limit(), "Consistency check");
78
79 old_gen()->initialize_work("old", 1);
80 assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(), "Consistency check");
81 assert(old_young_rs.size() >= old_gen()->gen_size_limit(), "Consistency check");
82
83 _virtual_spaces = hetero_virtual_spaces;
84 }
85
86 size_t AdjoiningGenerationsForHeteroHeap::required_reserved_memory(GenerationSizer* policy) {
87 // This is the size that young gen can grow to, when AdaptiveGCBoundary is true.
88 size_t max_yg_size = policy->max_heap_byte_size() - policy->min_old_size();
89 // This is the size that old gen can grow to, when AdaptiveGCBoundary is true.
90 size_t max_old_size = policy->max_heap_byte_size() - policy->min_young_size();
91
92 return max_yg_size + max_old_size;
93 }
94
95 // We override this function since size of reservedspace here is more than heap size and
96 // callers expect this function to return heap size.
97 size_t AdjoiningGenerationsForHeteroHeap::reserved_byte_size() {
98 return total_size_limit();
99 }
100
101 AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::HeteroVirtualSpaces(ReservedSpace rs, size_t min_old_byte_size, size_t min_yg_byte_size, size_t max_total_size, size_t alignment) :
102 AdjoiningVirtualSpaces(rs, min_old_byte_size, min_yg_byte_size, alignment),
103 _min_old_byte_size(min_old_byte_size), _min_young_byte_size(min_yg_byte_size),
104 _max_old_byte_size(_max_total_size - _min_young_byte_size),
105 _max_young_byte_size(_max_total_size - _min_old_byte_size),
106 _max_total_size(max_total_size) {
107 }
108
109 void AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::initialize(size_t initial_old_reserved_size, size_t init_old_byte_size,
110 size_t init_young_byte_size) {
111
112 // This is the reserved space exclusively for old generation.
113 ReservedSpace old_rs = _reserved_space.first_part(_max_old_byte_size, true);
114 // Intially we only assign 'initial_old_reserved_size' of the reserved space to old virtual space.
115 old_rs = old_rs.first_part(initial_old_reserved_size);
116
117 // This is the reserved space exclusively for young generation.
118 ReservedSpace young_rs = _reserved_space.last_part(_max_old_byte_size).first_part(_max_young_byte_size);
119
120 // Carve out 'initial_young_reserved_size' of reserved space.
121 size_t initial_young_reserved_size = _max_total_size - initial_old_reserved_size;
122 young_rs = young_rs.last_part(_max_young_byte_size - initial_young_reserved_size);
123
124 _low = new PSFileBackedVirtualSpace(old_rs, alignment(), AllocateOldGenAt);
125 if (!_low->expand_by(init_old_byte_size)) {
126 vm_exit_during_initialization("Could not reserve enough space for object heap");
127 }
128
129 _high = new PSVirtualSpaceHighToLow(young_rs, alignment());
130 if (!_high->expand_by(init_young_byte_size)) {
131 vm_exit_during_initialization("Could not reserve enough space for object heap");
132 }
133 }
134
135 // Since the virtual spaces are non-overlapping, there is no boundary as such.
136 // We replicate the same behavior and maintain the same invariants as base class - AdjoiningVirtualSpaces, by
137 // increasing old generation size and decreasing young generation size by same amount.
138 bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_up(size_t change_in_bytes) {
139 assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
140 DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size());
141
142 size_t bytes_needed = change_in_bytes;
143 size_t uncommitted_in_old = MIN2(old_vs()->uncommitted_size(), bytes_needed);
144 bool old_expanded = false;
145
146 // 1. Try to expand old within its reserved space.
147 if (uncommitted_in_old != 0) {
148 if (!old_vs()->expand_by(uncommitted_in_old)) {
149 return false;
150 }
151 old_expanded = true;
152 bytes_needed -= uncommitted_in_old;
153 if (bytes_needed == 0) {
154 return true;
155 }
156 }
157
158 size_t bytes_to_add_in_old = 0;
159
160 // 2. Get uncommitted memory from Young virtualspace.
161 size_t young_uncommitted = MIN2(young_vs()->uncommitted_size(), bytes_needed);
162 if (young_uncommitted > 0) {
163 young_vs()->set_reserved(young_vs()->reserved_low_addr() + young_uncommitted,
164 young_vs()->reserved_high_addr(),
165 young_vs()->special());
166 bytes_needed -= young_uncommitted;
167 bytes_to_add_in_old = young_uncommitted;
168 }
169
170 // 3. Get committed memory from Young virtualspace
171 if (bytes_needed > 0) {
172 size_t shrink_size = align_down(bytes_needed, young_vs()->alignment());
173 bool ret = young_vs()->shrink_by(shrink_size);
174 assert(ret, "We should be able to shrink young space");
175 young_vs()->set_reserved(young_vs()->reserved_low_addr() + shrink_size,
176 young_vs()->reserved_high_addr(),
177 young_vs()->special());
178
179 bytes_to_add_in_old += shrink_size;
180 }
181
182 // 4. Increase size of old space
183 old_vs()->set_reserved(old_vs()->reserved_low_addr(),
184 old_vs()->reserved_high_addr() + bytes_to_add_in_old,
185 old_vs()->special());
186 if (!old_vs()->expand_by(bytes_to_add_in_old) && !old_expanded) {
187 return false;
188 }
189
190 DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size());
191 assert(total_size_after == total_size_before, "should be equal");
192
193 return true;
194 }
195
196 // Read comment for adjust_boundary_up()
197 // Increase young generation size and decrease old generation size by same amount.
198 bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_down(size_t change_in_bytes) {
199 assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check");
200 DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size());
201
202 size_t bytes_needed = change_in_bytes;
203 size_t uncommitted_in_young = MIN2(young_vs()->uncommitted_size(), bytes_needed);
204 bool young_expanded = false;
205
206 // 1. Try to expand old within its reserved space.
207 if (uncommitted_in_young > 0) {
208 if (!young_vs()->expand_by(uncommitted_in_young)) {
209 return false;
210 }
211 young_expanded = true;
212 bytes_needed -= uncommitted_in_young;
213 if (bytes_needed == 0) {
214 return true;
215 }
216 }
217
218 size_t bytes_to_add_in_young = 0;
219
220 // 2. Get uncommitted memory from Old virtualspace.
221 size_t old_uncommitted = MIN2(old_vs()->uncommitted_size(), bytes_needed);
222 if (old_uncommitted > 0) {
223 old_vs()->set_reserved(old_vs()->reserved_low_addr(),
224 old_vs()->reserved_high_addr() - old_uncommitted,
225 old_vs()->special());
226 bytes_needed -= old_uncommitted;
227 bytes_to_add_in_young = old_uncommitted;
228 }
229
230 // 3. Get committed memory from Old virtualspace
231 if (bytes_needed > 0) {
232 size_t shrink_size = align_down(bytes_needed, old_vs()->alignment());
233 bool ret = old_vs()->shrink_by(shrink_size);
234 assert(ret, "We should be able to shrink young space");
235 old_vs()->set_reserved(old_vs()->reserved_low_addr(),
236 old_vs()->reserved_high_addr() - shrink_size,
237 old_vs()->special());
238
239 bytes_to_add_in_young += shrink_size;
240 }
241
242 assert(bytes_to_add_in_young <= change_in_bytes, "should not be more than requested size");
243 // 4. Increase size of young space
244 young_vs()->set_reserved(young_vs()->reserved_low_addr() - bytes_to_add_in_young,
245 young_vs()->reserved_high_addr(),
246 young_vs()->special());
247 if (!young_vs()->expand_by(bytes_to_add_in_young) && !young_expanded) {
248 return false;
249 }
250
251 DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size());
252 assert(total_size_after == total_size_before, "should be equal");
253
254 return true;
255 }
256
|