提交 4c7d14c1 编写于 作者: Z zgu

8054368: nsk/jdi/VirtualMachine/exit/exit002 crash with detail tracking on (NMT2)

Summary: Dynamic allocate _reserved_regions instead of static object to avoid racing during process exit
Reviewed-by: dholmes, coleenp
上级 a9af950f
...@@ -77,7 +77,12 @@ NMT_TrackingLevel MemTracker::init_tracking_level() { ...@@ -77,7 +77,12 @@ NMT_TrackingLevel MemTracker::init_tracking_level() {
} }
void MemTracker::init() { void MemTracker::init() {
if (tracking_level() >= NMT_summary) { NMT_TrackingLevel level = tracking_level();
if (level >= NMT_summary) {
if (!VirtualMemoryTracker::late_initialize(level)) {
shutdown();
return;
}
_query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock"); _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
// Already OOM. It is unlikely, but still have to handle it. // Already OOM. It is unlikely, but still have to handle it.
if (_query_lock == NULL) { if (_query_lock == NULL) {
......
...@@ -34,7 +34,7 @@ void VirtualMemorySummary::initialize() { ...@@ -34,7 +34,7 @@ void VirtualMemorySummary::initialize() {
::new ((void*)_snapshot) VirtualMemorySnapshot(); ::new ((void*)_snapshot) VirtualMemorySnapshot();
} }
SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base> VirtualMemoryTracker::_reserved_regions; SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* VirtualMemoryTracker::_reserved_regions;
int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) { int compare_committed_region(const CommittedMemoryRegion& r1, const CommittedMemoryRegion& r2) {
return r1.compare(r2); return r1.compare(r2);
...@@ -283,17 +283,26 @@ bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) { ...@@ -283,17 +283,26 @@ bool VirtualMemoryTracker::initialize(NMT_TrackingLevel level) {
return true; return true;
} }
bool VirtualMemoryTracker::late_initialize(NMT_TrackingLevel level) {
if (level >= NMT_summary) {
_reserved_regions = new (std::nothrow, ResourceObj::C_HEAP, mtNMT)
SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>();
return (_reserved_regions != NULL);
}
return true;
}
bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) { const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) {
assert(base_addr != NULL, "Invalid address"); assert(base_addr != NULL, "Invalid address");
assert(size > 0, "Invalid size"); assert(size > 0, "Invalid size");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(base_addr, size, stack, flag); ReservedMemoryRegion rgn(base_addr, size, stack, flag);
ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
LinkedListNode<ReservedMemoryRegion>* node; LinkedListNode<ReservedMemoryRegion>* node;
if (reserved_rgn == NULL) { if (reserved_rgn == NULL) {
VirtualMemorySummary::record_reserved_memory(size, flag); VirtualMemorySummary::record_reserved_memory(size, flag);
node = _reserved_regions.add(rgn); node = _reserved_regions->add(rgn);
if (node != NULL) { if (node != NULL) {
node->data()->set_all_committed(all_committed); node->data()->set_all_committed(all_committed);
return true; return true;
...@@ -338,9 +347,10 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size, ...@@ -338,9 +347,10 @@ bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) { void VirtualMemoryTracker::set_reserved_region_type(address addr, MEMFLAGS flag) {
assert(addr != NULL, "Invalid address"); assert(addr != NULL, "Invalid address");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(addr, 1); ReservedMemoryRegion rgn(addr, 1);
ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
if (reserved_rgn != NULL) { if (reserved_rgn != NULL) {
assert(reserved_rgn->contain_address(addr), "Containment"); assert(reserved_rgn->contain_address(addr), "Containment");
if (reserved_rgn->flag() != flag) { if (reserved_rgn->flag() != flag) {
...@@ -354,8 +364,10 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size, ...@@ -354,8 +364,10 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size,
const NativeCallStack& stack) { const NativeCallStack& stack) {
assert(addr != NULL, "Invalid address"); assert(addr != NULL, "Invalid address");
assert(size > 0, "Invalid size"); assert(size > 0, "Invalid size");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion rgn(addr, size);
ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
assert(reserved_rgn != NULL, "No reserved region"); assert(reserved_rgn != NULL, "No reserved region");
assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
...@@ -365,8 +377,10 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size, ...@@ -365,8 +377,10 @@ bool VirtualMemoryTracker::add_committed_region(address addr, size_t size,
bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) { bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) {
assert(addr != NULL, "Invalid address"); assert(addr != NULL, "Invalid address");
assert(size > 0, "Invalid size"); assert(size > 0, "Invalid size");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion rgn(addr, size);
ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
assert(reserved_rgn != NULL, "No reserved region"); assert(reserved_rgn != NULL, "No reserved region");
assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
return reserved_rgn->remove_uncommitted_region(addr, size); return reserved_rgn->remove_uncommitted_region(addr, size);
...@@ -375,9 +389,10 @@ bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size) ...@@ -375,9 +389,10 @@ bool VirtualMemoryTracker::remove_uncommitted_region(address addr, size_t size)
bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
assert(addr != NULL, "Invalid address"); assert(addr != NULL, "Invalid address");
assert(size > 0, "Invalid size"); assert(size > 0, "Invalid size");
assert(_reserved_regions != NULL, "Sanity check");
ReservedMemoryRegion rgn(addr, size); ReservedMemoryRegion rgn(addr, size);
ReservedMemoryRegion* reserved_rgn = _reserved_regions.find(rgn); ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
assert(reserved_rgn != NULL, "No reserved region"); assert(reserved_rgn != NULL, "No reserved region");
...@@ -390,7 +405,7 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { ...@@ -390,7 +405,7 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag()); VirtualMemorySummary::record_released_memory(size, reserved_rgn->flag());
if (reserved_rgn->same_region(addr, size)) { if (reserved_rgn->same_region(addr, size)) {
return _reserved_regions.remove(rgn); return _reserved_regions->remove(rgn);
} else { } else {
assert(reserved_rgn->contain_region(addr, size), "Not completely contained"); assert(reserved_rgn->contain_region(addr, size), "Not completely contained");
if (reserved_rgn->base() == addr || if (reserved_rgn->base() == addr ||
...@@ -405,7 +420,7 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { ...@@ -405,7 +420,7 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
// use original region for lower region // use original region for lower region
reserved_rgn->exclude_region(addr, top - addr); reserved_rgn->exclude_region(addr, top - addr);
LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions.add(high_rgn); LinkedListNode<ReservedMemoryRegion>* new_rgn = _reserved_regions->add(high_rgn);
if (new_rgn == NULL) { if (new_rgn == NULL) {
return false; return false;
} else { } else {
...@@ -418,8 +433,9 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) { ...@@ -418,8 +433,9 @@ bool VirtualMemoryTracker::remove_released_region(address addr, size_t size) {
bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) {
assert(_reserved_regions != NULL, "Sanity check");
ThreadCritical tc; ThreadCritical tc;
LinkedListNode<ReservedMemoryRegion>* head = _reserved_regions.head(); LinkedListNode<ReservedMemoryRegion>* head = _reserved_regions->head();
while (head != NULL) { while (head != NULL) {
const ReservedMemoryRegion* rgn = head->peek(); const ReservedMemoryRegion* rgn = head->peek();
if (!walker->do_allocation_site(rgn)) { if (!walker->do_allocation_site(rgn)) {
...@@ -439,7 +455,10 @@ bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel ...@@ -439,7 +455,10 @@ bool VirtualMemoryTracker::transition(NMT_TrackingLevel from, NMT_TrackingLevel
assert(from == NMT_summary || from == NMT_detail, "Just check"); assert(from == NMT_summary || from == NMT_detail, "Just check");
// Clean up virtual memory tracking data structures. // Clean up virtual memory tracking data structures.
ThreadCritical tc; ThreadCritical tc;
_reserved_regions.clear(); if (_reserved_regions != NULL) {
delete _reserved_regions;
_reserved_regions = NULL;
}
} }
return true; return true;
......
...@@ -414,6 +414,9 @@ class VirtualMemoryTracker : AllStatic { ...@@ -414,6 +414,9 @@ class VirtualMemoryTracker : AllStatic {
public: public:
static bool initialize(NMT_TrackingLevel level); static bool initialize(NMT_TrackingLevel level);
// Late phase initialization
static bool late_initialize(NMT_TrackingLevel level);
static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack, static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack,
MEMFLAGS flag = mtNone, bool all_committed = false); MEMFLAGS flag = mtNone, bool all_committed = false);
...@@ -428,7 +431,7 @@ class VirtualMemoryTracker : AllStatic { ...@@ -428,7 +431,7 @@ class VirtualMemoryTracker : AllStatic {
static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to); static bool transition(NMT_TrackingLevel from, NMT_TrackingLevel to);
private: private:
static SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base> _reserved_regions; static SortedLinkedList<ReservedMemoryRegion, compare_reserved_region_base>* _reserved_regions;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册