提交 b76445f8 编写于 作者: Z zgu

8139673: NMT stack traces in output should show mtcomponent

Summary: Show memory types of malloc site in detail report
Reviewed-by: dholmes, shade
上级 f3c992b0
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -97,7 +97,7 @@ bool MallocSiteTable::initialize() { ...@@ -97,7 +97,7 @@ bool MallocSiteTable::initialize() {
// Instantiate hash entry for hashtable entry allocation callsite // Instantiate hash entry for hashtable entry allocation callsite
MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site) MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site)
MallocSiteHashtableEntry(*stack); MallocSiteHashtableEntry(*stack, mtNMT);
// Add the allocation site to hashtable. // Add the allocation site to hashtable.
int index = hash_to_index(stack->hash()); int index = hash_to_index(stack->hash());
...@@ -134,7 +134,8 @@ bool MallocSiteTable::walk(MallocSiteWalker* walker) { ...@@ -134,7 +134,8 @@ bool MallocSiteTable::walk(MallocSiteWalker* walker) {
* Under any of above circumstances, caller should handle the situation. * Under any of above circumstances, caller should handle the situation.
*/ */
MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* bucket_idx, 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()); int index = hash_to_index(key.hash());
assert(index >= 0, "Negative index"); assert(index >= 0, "Negative index");
*bucket_idx = (size_t)index; *bucket_idx = (size_t)index;
...@@ -142,7 +143,7 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b ...@@ -142,7 +143,7 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b
// First entry for this hash bucket // First entry for this hash bucket
if (_table[index] == NULL) { if (_table[index] == NULL) {
MallocSiteHashtableEntry* entry = new_entry(key); MallocSiteHashtableEntry* entry = new_entry(key, flags);
// OOM check // OOM check
if (entry == NULL) return NULL; if (entry == NULL) return NULL;
...@@ -157,13 +158,12 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b ...@@ -157,13 +158,12 @@ MallocSite* MallocSiteTable::lookup_or_add(const NativeCallStack& key, size_t* b
MallocSiteHashtableEntry* head = _table[index]; MallocSiteHashtableEntry* head = _table[index];
while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) { while (head != NULL && (*pos_idx) <= MAX_BUCKET_LENGTH) {
MallocSite* site = head->data(); MallocSite* site = head->data();
if (site->equals(key)) { if (site->flags() == flags && site->equals(key)) {
// found matched entry
return head->data(); return head->data();
} }
if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) { if (head->next() == NULL && (*pos_idx) < MAX_BUCKET_LENGTH) {
MallocSiteHashtableEntry* entry = new_entry(key); MallocSiteHashtableEntry* entry = new_entry(key, flags);
// OOM check // OOM check
if (entry == NULL) return NULL; if (entry == NULL) return NULL;
if (head->atomic_insert(entry)) { if (head->atomic_insert(entry)) {
...@@ -192,10 +192,10 @@ MallocSite* MallocSiteTable::malloc_site(size_t bucket_idx, size_t pos_idx) { ...@@ -192,10 +192,10 @@ MallocSite* MallocSiteTable::malloc_site(size_t bucket_idx, size_t pos_idx) {
// Allocates MallocSiteHashtableEntry object. Special call stack // Allocates MallocSiteHashtableEntry object. Special call stack
// (pre-installed allocation site) has to be used to avoid infinite // (pre-installed allocation site) has to be used to avoid infinite
// recursion. // recursion.
MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key) { MallocSiteHashtableEntry* MallocSiteTable::new_entry(const NativeCallStack& key, MEMFLAGS flags) {
void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT, void* p = AllocateHeap(sizeof(MallocSiteHashtableEntry), mtNMT,
*hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL); *hash_entry_allocation_stack(), AllocFailStrategy::RETURN_NULL);
return ::new (p) MallocSiteHashtableEntry(key); return ::new (p) MallocSiteHashtableEntry(key, flags);
} }
void MallocSiteTable::reset() { void MallocSiteTable::reset() {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,12 +37,16 @@ ...@@ -37,12 +37,16 @@
// MallocSite represents a code path that eventually calls // MallocSite represents a code path that eventually calls
// os::malloc() to allocate memory // os::malloc() to allocate memory
class MallocSite : public AllocationSite<MemoryCounter> { class MallocSite : public AllocationSite<MemoryCounter> {
private:
MEMFLAGS _flags;
public: public:
MallocSite() : MallocSite() :
AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK) { } AllocationSite<MemoryCounter>(NativeCallStack::EMPTY_STACK), _flags(mtNone) {}
MallocSite(const NativeCallStack& stack, MEMFLAGS flags) :
AllocationSite<MemoryCounter>(stack), _flags(flags) {}
MallocSite(const NativeCallStack& stack) :
AllocationSite<MemoryCounter>(stack) { }
void allocate(size_t size) { data()->allocate(size); } void allocate(size_t size) { data()->allocate(size); }
void deallocate(size_t size) { data()->deallocate(size); } void deallocate(size_t size) { data()->deallocate(size); }
...@@ -51,6 +55,7 @@ class MallocSite : public AllocationSite<MemoryCounter> { ...@@ -51,6 +55,7 @@ class MallocSite : public AllocationSite<MemoryCounter> {
size_t size() const { return peek()->size(); } size_t size() const { return peek()->size(); }
// The number of calls were made // The number of calls were made
size_t count() const { return peek()->count(); } size_t count() const { return peek()->count(); }
MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
}; };
// Malloc site hashtable entry // Malloc site hashtable entry
...@@ -62,8 +67,10 @@ class MallocSiteHashtableEntry : public CHeapObj<mtNMT> { ...@@ -62,8 +67,10 @@ class MallocSiteHashtableEntry : public CHeapObj<mtNMT> {
public: public:
MallocSiteHashtableEntry() : _next(NULL) { } MallocSiteHashtableEntry() : _next(NULL) { }
MallocSiteHashtableEntry(NativeCallStack stack): MallocSiteHashtableEntry(NativeCallStack stack, MEMFLAGS flags):
_malloc_site(stack), _next(NULL) { } _malloc_site(stack, flags), _next(NULL) {
assert(flags != mtNone, "Expect a real memory type");
}
inline const MallocSiteHashtableEntry* next() const { inline const MallocSiteHashtableEntry* next() const {
return _next; return _next;
...@@ -198,11 +205,11 @@ class MallocSiteTable : AllStatic { ...@@ -198,11 +205,11 @@ class MallocSiteTable : AllStatic {
// 1. out of memory // 1. out of memory
// 2. overflow hash bucket // 2. overflow hash bucket
static inline bool allocation_at(const NativeCallStack& stack, size_t size, 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); AccessLock locker(&_access_count);
if (locker.sharedLock()) { if (locker.sharedLock()) {
NOT_PRODUCT(_peak_count = MAX2(_peak_count, _access_count);) 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); if (site != NULL) site->allocate(size);
return site != NULL; return site != NULL;
} }
...@@ -228,13 +235,13 @@ class MallocSiteTable : AllStatic { ...@@ -228,13 +235,13 @@ class MallocSiteTable : AllStatic {
static bool walk_malloc_site(MallocSiteWalker* walker); static bool walk_malloc_site(MallocSiteWalker* walker);
private: private:
static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key); static MallocSiteHashtableEntry* new_entry(const NativeCallStack& key, MEMFLAGS flags);
static void reset(); static void reset();
// Delete a bucket linked list // Delete a bucket linked list
static void delete_linked_list(MallocSiteHashtableEntry* head); 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 MallocSite* malloc_site(size_t bucket_idx, size_t pos_idx);
static bool walk(MallocSiteWalker* walker); static bool walk(MallocSiteWalker* walker);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -78,8 +78,8 @@ void MallocHeader::release() const { ...@@ -78,8 +78,8 @@ void MallocHeader::release() const {
} }
bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size, bool MallocHeader::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 {
bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx); bool ret = MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags);
// Something went wrong, could be OOM or overflow malloc site table. // Something went wrong, could be OOM or overflow malloc site table.
// We want to keep tracking data under OOM circumstance, so transition to // We want to keep tracking data under OOM circumstance, so transition to
......
...@@ -268,7 +268,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC { ...@@ -268,7 +268,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC {
if (level == NMT_detail) { if (level == NMT_detail) {
size_t bucket_idx; size_t bucket_idx;
size_t pos_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(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index"); assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
_bucket_idx = bucket_idx; _bucket_idx = bucket_idx;
...@@ -292,7 +292,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC { ...@@ -292,7 +292,7 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC {
_size = size; _size = size;
} }
bool record_malloc_site(const NativeCallStack& stack, size_t 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;
}; };
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 { ...@@ -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); 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(); const char* scale = current_scale();
outputStream* out = output(); outputStream* out = output();
out->print("(malloc=" SIZE_FORMAT "%s", if (flag != mtNone) {
amount_in_current_scale(amount), scale); 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) { if (count > 0) {
out->print(" #" SIZE_FORMAT "", count); out->print(" #" SIZE_FORMAT "", count);
...@@ -200,7 +205,10 @@ void MemDetailReporter::report_malloc_sites() { ...@@ -200,7 +205,10 @@ void MemDetailReporter::report_malloc_sites() {
const NativeCallStack* stack = malloc_site->call_stack(); const NativeCallStack* stack = malloc_site->call_stack();
stack->print_on(out); stack->print_on(out);
out->print("%29s", " "); 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"); out->print_cr("\n");
} }
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -76,7 +76,7 @@ class MemReporterBase : public StackObj { ...@@ -76,7 +76,7 @@ class MemReporterBase : public StackObj {
// Print summary total, malloc and virtual memory // Print summary total, malloc and virtual memory
void print_total(size_t reserved, size_t committed) const; 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_virtual_memory(size_t reserved, size_t committed) const;
void print_malloc_line(size_t amount, size_t count) const; void print_malloc_line(size_t amount, size_t count) const;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册