From b76445f8a230341dd040ca838dc5a259fed9e296 Mon Sep 17 00:00:00 2001 From: zgu Date: Wed, 8 Nov 2017 09:07:05 -0500 Subject: [PATCH] 8139673: NMT stack traces in output should show mtcomponent Summary: Show memory types of malloc site in detail report Reviewed-by: dholmes, shade --- src/share/vm/services/mallocSiteTable.cpp | 18 +++++++-------- src/share/vm/services/mallocSiteTable.hpp | 27 ++++++++++++++--------- src/share/vm/services/mallocTracker.cpp | 6 ++--- src/share/vm/services/mallocTracker.hpp | 4 ++-- src/share/vm/services/memReporter.cpp | 18 ++++++++++----- src/share/vm/services/memReporter.hpp | 4 ++-- 6 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/share/vm/services/mallocSiteTable.cpp b/src/share/vm/services/mallocSiteTable.cpp index 8090de8b9..861c5a35b 100644 --- a/src/share/vm/services/mallocSiteTable.cpp +++ b/src/share/vm/services/mallocSiteTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,7 @@ bool MallocSiteTable::initialize() { // Instantiate hash entry for hashtable entry allocation callsite MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site) - MallocSiteHashtableEntry(*stack); + MallocSiteHashtableEntry(*stack, mtNMT); // Add the allocation site to hashtable. int index = hash_to_index(stack->hash()); @@ -134,7 +134,8 @@ bool MallocSiteTable::walk(MallocSiteWalker* walker) { * Under any of above circumstances, caller should handle the situation. */ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, - size_t* pos_idx) { + size_t* pos_idx, MEMFLAGS flags) { + assert(flags != mtNone, "Should have a real memory type"); int index = hash_to_index(key.hash()); assert(index >= 0, "Negative index"); *bucket_idx = (size_t)index; @@ -142,7 +143,7 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b // First entry for this hash bucket if (_table[index] == NULL) { - MallocSiteHashtableEntry* entry = new_entry(key); + MallocSiteHashtableEntry* entry = new_entry(key, flags); // OOM check if (entry == NULL) return NULL; @@ -157,13 +158,12 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b MallocSiteHashtableEntry* head = _table[index]; while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { MallocSite* site = head->data(); - if (site->equals(key)) { - // found matched entry + if (site->flags() == flags && site->equals(key)) { return head->data(); } if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) { - MallocSiteHashtableEntry* entry = new_entry(key); + MallocSiteHashtableEntry* entry = new_entry(key, flags); // OOM check if (entry == NULL) return NULL; if (head->atomic_insert(entry)) { @@ -192,10 +192,10 @@ MallocSite* MallocSiteTable::malloc_site(size_t bucket_idx, size_t pos_idx) { // Allocates MallocSiteHashtableEntry object. Special call stack // (pre-installed allocation site) has to be used to avoid infinite // recursion. -MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key) { +MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key, MEMFLAGS flags) { void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT, *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL); - return ::new (p) MallocSiteHashtableEntry(key); + return ::new (p) MallocSiteHashtableEntry(key, flags); } void MallocSiteTable::reset() { diff --git a/src/share/vm/services/mallocSiteTable.hpp b/src/share/vm/services/mallocSiteTable.hpp index cff981614..36c4e5c56 100644 --- a/src/share/vm/services/mallocSiteTable.hpp +++ b/src/share/vm/services/mallocSiteTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,12 +37,16 @@ // MallocSite represents a code path that eventually calls // os::malloc() to allocate memory class MallocSite : public AllocationSite { + private: + MEMFLAGS _flags; + public: MallocSite() : - AllocationSite(NativeCallStack::EMPTY_STACK) { } + AllocationSite(NativeCallStack::EMPTY_STACK), _flags(mtNone) {} + + MallocSite(const NativeCallStack& stack, MEMFLAGS flags) : + AllocationSite(stack), _flags(flags) {} - MallocSite(const NativeCallStack& stack) : - AllocationSite(stack) { } void allocate(size_t size) { data()->allocate(size); } void deallocate(size_t size) { data()->deallocate(size); } @@ -51,6 +55,7 @@ class MallocSite : public AllocationSite { size_t size() const { return peek()->size(); } // The number of calls were made size_t count() const { return peek()->count(); } + MEMFLAGS flags() const { return (MEMFLAGS)_flags; } }; // Malloc site hashtable entry @@ -62,8 +67,10 @@ class MallocSiteHashtableEntry : public CHeapObj { public: MallocSiteHashtableEntry() : _next(NULL) { } - MallocSiteHashtableEntry(NativeCallStack stack): - _malloc_site(stack), _next(NULL) { } + MallocSiteHashtableEntry(NativeCallStack stack, MEMFLAGS flags): + _malloc_site(stack, flags), _next(NULL) { + assert(flags != mtNone, "Expect a real memory type"); + } inline const MallocSiteHashtableEntry* next() const { return _next; @@ -198,11 +205,11 @@ class MallocSiteTable : AllStatic { // 1. out of memory // 2. overflow hash bucket static inline bool allocation_at(const NativeCallStack& stack, size_t size, - size_t* bucket_idx, size_t* pos_idx) { + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) { AccessLock locker(&_access_count); if (locker.sharedLock()) { NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) - MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx); + MallocSite* site = lookup_or_add(stack, bucket_idx, pos_idx, flags); if (site != NULL) site->allocate(size); return site != NULL; } @@ -228,13 +235,13 @@ class MallocSiteTable : AllStatic { static bool walk_malloc_site(MallocSiteWalker* walker); private: - static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key); + static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key, MEMFLAGS flags); static void reset(); // Delete a bucket linked list static void delete_linked_list(MallocSiteHashtableEntry* head); - static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx); + static MallocSite* lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags); static MallocSite* malloc_site(size_t bucket_idx, size_t pos_idx); static bool walk(MallocSiteWalker* walker); diff --git a/src/share/vm/services/mallocTracker.cpp b/src/share/vm/services/mallocTracker.cpp index dc4f08f94..8d32df312 100644 --- a/src/share/vm/services/mallocTracker.cpp +++ b/src/share/vm/services/mallocTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,8 +78,8 @@ void MallocHeader::release() const { } bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size, - size_t* bucket_idx, size_t* pos_idx) const { - bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx); + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const { + bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags); // Something went wrong, could be OOM or overflow malloc site table. // We want to keep tracking data under OOM circumstance, so transition to diff --git a/src/share/vm/services/mallocTracker.hpp b/src/share/vm/services/mallocTracker.hpp index 3c61aa432..d770e41ae 100644 --- a/src/share/vm/services/mallocTracker.hpp +++ b/src/share/vm/services/mallocTracker.hpp @@ -268,7 +268,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC { if (level == NMT_detail) { size_t bucket_idx; size_t pos_idx; - if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) { + if (record_malloc_site(stack, size, &bucket_idx, &pos_idx, flags)) { assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index"); assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index"); _bucket_idx = bucket_idx; @@ -292,7 +292,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC { _size = size; } bool record_malloc_site(const NativeCallStack& stack, size_t size, - size_t* bucket_idx, size_t* pos_idx) const; + size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const; }; diff --git a/src/share/vm/services/memReporter.cpp b/src/share/vm/services/memReporter.cpp index 026961917..dfc4e4d45 100644 --- a/src/share/vm/services/memReporter.cpp +++ b/src/share/vm/services/memReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,11 +43,16 @@ void MemReporterBase::print_total(size_t reserved, size_t committed) const { amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale); } -void MemReporterBase::print_malloc(size_t amount, size_t count) const { +void MemReporterBase::print_malloc(size_t amount, size_t count, MEMFLAGS flag) const { const char* scale = current_scale(); outputStream* out = output(); - out->print("(malloc=" SIZE_FORMAT "%s", - amount_in_current_scale(amount), scale); + if (flag != mtNone) { + out->print("(malloc=" SIZE_FORMAT "%s type=%s", + amount_in_current_scale(amount), scale, NMTUtil::flag_to_name(flag)); + } else { + out->print("(malloc=" SIZE_FORMAT "%s", + amount_in_current_scale(amount), scale); + } if (count > 0) { out->print(" #" SIZE_FORMAT "", count); @@ -200,7 +205,10 @@ void MemDetailReporter::report_malloc_sites() { const NativeCallStack* stack = malloc_site->call_stack(); stack->print_on(out); out->print("%29s", " "); - print_malloc(malloc_site->size(), malloc_site->count()); + MEMFLAGS flag = malloc_site->flags(); + assert((flag >= 0 && flag < (int)mt_number_of_types) && flag != mtNone, + "Must have a valid memory type"); + print_malloc(malloc_site->size(), malloc_site->count(),flag); out->print_cr("\n"); } } diff --git a/src/share/vm/services/memReporter.hpp b/src/share/vm/services/memReporter.hpp index 951076c93..50b6b7f8c 100644 --- a/src/share/vm/services/memReporter.hpp +++ b/src/share/vm/services/memReporter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ class MemReporterBase : public StackObj { // Print summary total, malloc and virtual memory void print_total(size_t reserved, size_t committed) const; - void print_malloc(size_t amount, size_t count) const; + void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const; void print_virtual_memory(size_t reserved, size_t committed) const; void print_malloc_line(size_t amount, size_t count) const; -- GitLab