8139673: NMT stack traces in output should show mtcomponent
Summary: Show memory types of malloc site in detail report
Reviewed-by: dholmes, shade, coleenp
Contributed-by: max.ockner@oracle.com, zgu@redhat.com
--- a/hotspot/src/share/vm/services/mallocSiteTable.cpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocSiteTable.cpp Tue May 23 11:58:32 2017 -0400
@@ -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 @@
// 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,14 +134,15 @@
* 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");
unsigned int index = hash_to_index(key.hash());
*bucket_idx = (size_t)index;
*pos_idx = 0;
// 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;
@@ -156,13 +157,12 @@
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)) {
@@ -191,10 +191,10 @@
// 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() {
--- a/hotspot/src/share/vm/services/mallocSiteTable.hpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocSiteTable.hpp Tue May 23 11:58:32 2017 -0400
@@ -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<MemoryCounter> {
+ private:
+ MEMFLAGS _flags;
+
public:
MallocSite() :
- AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK) { }
+ AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK), _flags(mtNone) {}
- MallocSite(const NativeCallStack& stack) :
- AllocationSite<MemoryCounter>(stack) { }
+ MallocSite(const NativeCallStack& stack, MEMFLAGS flags) :
+ AllocationSite<MemoryCounter>(stack), _flags(flags) {}
+
void allocate(size_t size) { data()->allocate(size); }
void deallocate(size_t size) { data()->deallocate(size); }
@@ -51,6 +55,7 @@
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 @@
public:
MallocSiteHashtableEntry() : _next(NULL) { }
- MallocSiteHashtableEntry(const 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 @@
// 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 @@
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);
--- a/hotspot/src/share/vm/services/mallocTracker.cpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocTracker.cpp Tue May 23 11:58:32 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, 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
@@ -77,8 +77,8 @@
}
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
--- a/hotspot/src/share/vm/services/mallocTracker.hpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocTracker.hpp Tue May 23 11:58:32 2017 -0400
@@ -275,7 +275,7 @@
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;
@@ -299,7 +299,7 @@
_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;
};
--- a/hotspot/src/share/vm/services/memReporter.cpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/memReporter.cpp Tue May 23 11:58:32 2017 -0400
@@ -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 @@
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 @@
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");
}
}
--- a/hotspot/src/share/vm/services/memReporter.hpp Tue May 09 16:48:31 2017 +0200
+++ b/hotspot/src/share/vm/services/memReporter.hpp Tue May 23 11:58:32 2017 -0400
@@ -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 @@
// 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;