32 assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); |
32 assert(sizeof(_snapshot) >= sizeof(VirtualMemorySnapshot), "Sanity Check"); |
33 // Use placement operator new to initialize static data area. |
33 // Use placement operator new to initialize static data area. |
34 ::new ((void*)_snapshot) VirtualMemorySnapshot(); |
34 ::new ((void*)_snapshot) VirtualMemorySnapshot(); |
35 } |
35 } |
36 |
36 |
37 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base> VirtualMemoryTracker::_reserved_regions; |
37 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions; |
38 |
38 |
39 int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) { |
39 int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) { |
40 return r1.compare(r2); |
40 return r1.compare(r2); |
41 } |
41 } |
42 |
42 |
281 VirtualMemorySummary::initialize(); |
281 VirtualMemorySummary::initialize(); |
282 } |
282 } |
283 return true; |
283 return true; |
284 } |
284 } |
285 |
285 |
|
286 bool VirtualMemoryTracker::late_initialize(NMT_TrackingLevel level) { |
|
287 if (level >= NMT_summary) { |
|
288 _reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT) |
|
289 SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>(); |
|
290 return (_reserved_regions != NULL); |
|
291 } |
|
292 return true; |
|
293 } |
|
294 |
286 bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, |
295 bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, |
287 const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) { |
296 const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) { |
288 assert(base_addr != NULL, "Invalid address"); |
297 assert(base_addr != NULL, "Invalid address"); |
289 assert(size > 0, "Invalid size"); |
298 assert(size > 0, "Invalid size"); |
290 |
299 assert(_reserved_regions != NULL, "Sanity check"); |
291 ReservedMemoryRegion rgn(base_addr, size, stack, flag); |
300 ReservedMemoryRegion rgn(base_addr, size, stack, flag); |
292 ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); |
301 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
293 LinkedListNode<ReservedMemoryRegion>* node; |
302 LinkedListNode<ReservedMemoryRegion>* node; |
294 if (reserved_rgn == NULL) { |
303 if (reserved_rgn == NULL) { |
295 VirtualMemorySummary::record_reserved_memory(size, flag); |
304 VirtualMemorySummary::record_reserved_memory(size, flag); |
296 node = _reserved_regions.add(rgn); |
305 node = _reserved_regions->add(rgn); |
297 if (node != NULL) { |
306 if (node != NULL) { |
298 node->data()->set_all_committed(all_committed); |
307 node->data()->set_all_committed(all_committed); |
299 return true; |
308 return true; |
300 } else { |
309 } else { |
301 return false; |
310 return false; |
336 } |
345 } |
337 } |
346 } |
338 |
347 |
339 void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) { |
348 void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) { |
340 assert(addr != NULL, "Invalid address"); |
349 assert(addr != NULL, "Invalid address"); |
|
350 assert(_reserved_regions != NULL, "Sanity check"); |
341 |
351 |
342 ReservedMemoryRegion rgn(addr, 1); |
352 ReservedMemoryRegion rgn(addr, 1); |
343 ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); |
353 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
344 if (reserved_rgn != NULL) { |
354 if (reserved_rgn != NULL) { |
345 assert(reserved_rgn->contain_address(addr), "Containment"); |
355 assert(reserved_rgn->contain_address(addr), "Containment"); |
346 if (reserved_rgn->flag() != flag) { |
356 if (reserved_rgn->flag() != flag) { |
347 assert(reserved_rgn->flag() == mtNone, "Overwrite memory type"); |
357 assert(reserved_rgn->flag() == mtNone, "Overwrite memory type"); |
348 reserved_rgn->set_flag(flag); |
358 reserved_rgn->set_flag(flag); |
352 |
362 |
353 bool VirtualMemoryTracker::add_committed_region(address addr, size_t size, |
363 bool VirtualMemoryTracker::add_committed_region(address addr, size_t size, |
354 const NativeCallStack& stack) { |
364 const NativeCallStack& stack) { |
355 assert(addr != NULL, "Invalid address"); |
365 assert(addr != NULL, "Invalid address"); |
356 assert(size > 0, "Invalid size"); |
366 assert(size > 0, "Invalid size"); |
|
367 assert(_reserved_regions != NULL, "Sanity check"); |
|
368 |
357 ReservedMemoryRegion rgn(addr, size); |
369 ReservedMemoryRegion rgn(addr, size); |
358 ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); |
370 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
359 |
371 |
360 assert(reserved_rgn != NULL, "No reserved region"); |
372 assert(reserved_rgn != NULL, "No reserved region"); |
361 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
373 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
362 return reserved_rgn->add_committed_region(addr, size, stack); |
374 return reserved_rgn->add_committed_region(addr, size, stack); |
363 } |
375 } |
364 |
376 |
365 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { |
377 bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { |
366 assert(addr != NULL, "Invalid address"); |
378 assert(addr != NULL, "Invalid address"); |
367 assert(size > 0, "Invalid size"); |
379 assert(size > 0, "Invalid size"); |
|
380 assert(_reserved_regions != NULL, "Sanity check"); |
|
381 |
368 ReservedMemoryRegion rgn(addr, size); |
382 ReservedMemoryRegion rgn(addr, size); |
369 ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); |
383 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
370 assert(reserved_rgn != NULL, "No reserved region"); |
384 assert(reserved_rgn != NULL, "No reserved region"); |
371 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
385 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
372 return reserved_rgn->remove_uncommitted_region(addr, size); |
386 return reserved_rgn->remove_uncommitted_region(addr, size); |
373 } |
387 } |
374 |
388 |
375 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { |
389 bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { |
376 assert(addr != NULL, "Invalid address"); |
390 assert(addr != NULL, "Invalid address"); |
377 assert(size > 0, "Invalid size"); |
391 assert(size > 0, "Invalid size"); |
|
392 assert(_reserved_regions != NULL, "Sanity check"); |
378 |
393 |
379 ReservedMemoryRegion rgn(addr, size); |
394 ReservedMemoryRegion rgn(addr, size); |
380 ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); |
395 ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn); |
381 |
396 |
382 assert(reserved_rgn != NULL, "No reserved region"); |
397 assert(reserved_rgn != NULL, "No reserved region"); |
383 |
398 |
384 // uncommit regions within the released region |
399 // uncommit regions within the released region |
385 if (!reserved_rgn->remove_uncommitted_region(addr, size)) { |
400 if (!reserved_rgn->remove_uncommitted_region(addr, size)) { |
388 |
403 |
389 |
404 |
390 VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag()); |
405 VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag()); |
391 |
406 |
392 if (reserved_rgn->same_region(addr, size)) { |
407 if (reserved_rgn->same_region(addr, size)) { |
393 return _reserved_regions.remove(rgn); |
408 return _reserved_regions->remove(rgn); |
394 } else { |
409 } else { |
395 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
410 assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); |
396 if (reserved_rgn->base() == addr || |
411 if (reserved_rgn->base() == addr || |
397 reserved_rgn->end() == addr + size) { |
412 reserved_rgn->end() == addr + size) { |
398 reserved_rgn->exclude_region(addr, size); |
413 reserved_rgn->exclude_region(addr, size); |
403 ReservedMemoryRegion high_rgn(high_base, top - high_base, |
418 ReservedMemoryRegion high_rgn(high_base, top - high_base, |
404 *reserved_rgn->call_stack(), reserved_rgn->flag()); |
419 *reserved_rgn->call_stack(), reserved_rgn->flag()); |
405 |
420 |
406 // use original region for lower region |
421 // use original region for lower region |
407 reserved_rgn->exclude_region(addr, top - addr); |
422 reserved_rgn->exclude_region(addr, top - addr); |
408 LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions.add(high_rgn); |
423 LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions->add(high_rgn); |
409 if (new_rgn == NULL) { |
424 if (new_rgn == NULL) { |
410 return false; |
425 return false; |
411 } else { |
426 } else { |
412 reserved_rgn->move_committed_regions(addr, *new_rgn->data()); |
427 reserved_rgn->move_committed_regions(addr, *new_rgn->data()); |
413 return true; |
428 return true; |