213 uint node_index = preferred_node_index_for_index(region_index); |
215 uint node_index = preferred_node_index_for_index(region_index); |
214 |
216 |
215 assert(is_aligned(aligned_address, page_size()), "Given address (" PTR_FORMAT ") should be aligned.", p2i(aligned_address)); |
217 assert(is_aligned(aligned_address, page_size()), "Given address (" PTR_FORMAT ") should be aligned.", p2i(aligned_address)); |
216 assert(is_aligned(size_in_bytes, page_size()), "Given size (" SIZE_FORMAT ") should be aligned.", size_in_bytes); |
218 assert(is_aligned(size_in_bytes, page_size()), "Given size (" SIZE_FORMAT ") should be aligned.", size_in_bytes); |
217 |
219 |
218 log_debug(gc, heap, numa)("Request memory [" PTR_FORMAT ", " PTR_FORMAT ") to be numa id (%d).", |
220 log_trace(gc, heap, numa)("Request memory [" PTR_FORMAT ", " PTR_FORMAT ") to be NUMA id (%d)", |
219 p2i(aligned_address), p2i((char*)aligned_address + size_in_bytes), _node_ids[node_index]); |
221 p2i(aligned_address), p2i((char*)aligned_address + size_in_bytes), _node_ids[node_index]); |
220 os::numa_make_local((char*)aligned_address, size_in_bytes, _node_ids[node_index]); |
222 os::numa_make_local((char*)aligned_address, size_in_bytes, _node_ids[node_index]); |
221 } |
223 } |
222 |
224 |
223 uint G1NUMA::max_search_depth() const { |
225 uint G1NUMA::max_search_depth() const { |
224 // Multiple of 3 is just random number to limit iterations. |
226 // Multiple of 3 is just random number to limit iterations. |
225 // There would be some cases that 1 page may be consisted of multiple HeapRegions. |
227 // There would be some cases that 1 page may be consisted of multiple HeapRegions. |
226 return 3 * MAX2((uint)(page_size() / region_size()), (uint)1) * num_active_nodes(); |
228 return 3 * MAX2((uint)(page_size() / region_size()), (uint)1) * num_active_nodes(); |
227 } |
229 } |
|
230 |
|
231 void G1NUMA::update_statistics(G1NUMAStats::NodeDataItems phase, |
|
232 uint requested_node_index, |
|
233 uint allocated_node_index) { |
|
234 if (_stats == NULL) { |
|
235 return; |
|
236 } |
|
237 |
|
238 uint converted_req_index; |
|
239 if(requested_node_index < _num_active_node_ids) { |
|
240 converted_req_index = requested_node_index; |
|
241 } else { |
|
242 assert(requested_node_index == AnyNodeIndex, |
|
243 "Requested node index %u should be AnyNodeIndex.", requested_node_index); |
|
244 converted_req_index = _num_active_node_ids; |
|
245 } |
|
246 _stats->update(phase, converted_req_index, allocated_node_index); |
|
247 } |
|
248 |
|
249 void G1NUMA::copy_statistics(G1NUMAStats::NodeDataItems phase, |
|
250 uint requested_node_index, |
|
251 size_t* allocated_stat) { |
|
252 if (_stats == NULL) { |
|
253 return; |
|
254 } |
|
255 |
|
256 _stats->copy(phase, requested_node_index, allocated_stat); |
|
257 } |
|
258 |
|
259 void G1NUMA::print_statistics() const { |
|
260 if (_stats == NULL) { |
|
261 return; |
|
262 } |
|
263 |
|
264 _stats->print_statistics(); |
|
265 } |
|
266 |
|
267 G1NodeIndexCheckClosure::G1NodeIndexCheckClosure(const char* desc, G1NUMA* numa, LogStream* ls) : |
|
268 _desc(desc), _numa(numa), _ls(ls) { |
|
269 |
|
270 uint num_nodes = _numa->num_active_nodes(); |
|
271 _matched = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC); |
|
272 _mismatched = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC); |
|
273 _total = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC); |
|
274 memset(_matched, 0, sizeof(uint) * num_nodes); |
|
275 memset(_mismatched, 0, sizeof(uint) * num_nodes); |
|
276 memset(_total, 0, sizeof(uint) * num_nodes); |
|
277 } |
|
278 |
|
279 G1NodeIndexCheckClosure::~G1NodeIndexCheckClosure() { |
|
280 _ls->print("%s: NUMA region verification (id: matched/mismatched/total): ", _desc); |
|
281 const int* numa_ids = _numa->node_ids(); |
|
282 for (uint i = 0; i < _numa->num_active_nodes(); i++) { |
|
283 _ls->print("%d: %u/%u/%u ", numa_ids[i], _matched[i], _mismatched[i], _total[i]); |
|
284 } |
|
285 |
|
286 FREE_C_HEAP_ARRAY(uint, _matched); |
|
287 FREE_C_HEAP_ARRAY(uint, _mismatched); |
|
288 FREE_C_HEAP_ARRAY(uint, _total); |
|
289 } |
|
290 |
|
291 bool G1NodeIndexCheckClosure::do_heap_region(HeapRegion* hr) { |
|
292 // Preferred node index will only have valid node index. |
|
293 uint preferred_node_index = _numa->preferred_node_index_for_index(hr->hrm_index()); |
|
294 // Active node index may have UnknownNodeIndex. |
|
295 uint active_node_index = _numa->index_of_address(hr->bottom()); |
|
296 |
|
297 if (preferred_node_index == active_node_index) { |
|
298 _matched[preferred_node_index]++; |
|
299 } else if (active_node_index != G1NUMA::UnknownNodeIndex) { |
|
300 _mismatched[preferred_node_index]++; |
|
301 } |
|
302 _total[preferred_node_index]++; |
|
303 |
|
304 return false; |
|
305 } |