8139673: NMT stack traces in output should show mtcomponent
authorzgu
Tue, 23 May 2017 11:58:32 -0400
changeset 46489 40abcea5a9d5
parent 46487 f8e5223d1501
child 46490 d530e842c512
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
hotspot/src/share/vm/services/mallocSiteTable.cpp
hotspot/src/share/vm/services/mallocSiteTable.hpp
hotspot/src/share/vm/services/mallocTracker.cpp
hotspot/src/share/vm/services/mallocTracker.hpp
hotspot/src/share/vm/services/memReporter.cpp
hotspot/src/share/vm/services/memReporter.hpp
--- 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;