hotspot/src/share/vm/services/memBaseline.hpp
changeset 25946 1572c9f03fb9
parent 17074 d660347efb98
child 26288 631bf42cf7c2
--- a/hotspot/src/share/vm/services/memBaseline.hpp	Tue Aug 05 14:18:44 2014 +0000
+++ b/hotspot/src/share/vm/services/memBaseline.hpp	Thu Aug 07 12:18:58 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -25,425 +25,205 @@
 #ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
 #define SHARE_VM_SERVICES_MEM_BASELINE_HPP
 
+#if INCLUDE_NMT
+
 #include "memory/allocation.hpp"
 #include "runtime/mutex.hpp"
-#include "services/memPtr.hpp"
-#include "services/memSnapshot.hpp"
+#include "services/mallocSiteTable.hpp"
+#include "services/mallocTracker.hpp"
+#include "services/nmtCommon.hpp"
+#include "services/virtualMemoryTracker.hpp"
+#include "utilities/linkedlist.hpp"
 
-// compare unsigned number
-#define UNSIGNED_COMPARE(a, b)  ((a > b) ? 1 : ((a == b) ? 0 : -1))
+typedef LinkedListIterator<MallocSite>                   MallocSiteIterator;
+typedef LinkedListIterator<VirtualMemoryAllocationSite>  VirtualMemorySiteIterator;
+typedef LinkedListIterator<ReservedMemoryRegion>         VirtualMemoryAllocationIterator;
 
 /*
- * MallocCallsitePointer and VMCallsitePointer are used
- * to baseline memory blocks with their callsite information.
- * They are only available when detail tracking is turned
- * on.
+ * Baseline a memory snapshot
  */
-
-/* baselined malloc record aggregated by callsite */
-class MallocCallsitePointer : public MemPointer {
- private:
-  size_t    _count;   // number of malloc invocation from this callsite
-  size_t    _amount;  // total amount of memory malloc-ed from this callsite
-
+class MemBaseline VALUE_OBJ_CLASS_SPEC {
  public:
-  MallocCallsitePointer() {
-    _count = 0;
-    _amount = 0;
-  }
-
-  MallocCallsitePointer(address pc) : MemPointer(pc) {
-    _count = 0;
-    _amount = 0;
-  }
+  enum BaselineThreshold {
+    SIZE_THRESHOLD = K        // Only allocation size over this threshold will be baselined.
+  };
 
-  MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
-    MemPointer::operator=(p);
-    _count = p.count();
-    _amount = p.amount();
-    return *this;
-  }
+  enum BaselineType {
+    Not_baselined,
+    Summary_baselined,
+    Detail_baselined
+  };
 
-  inline void inc(size_t size) {
-    _count ++;
-    _amount += size;
+  enum SortingOrder {
+    by_address,   // by memory address
+    by_size,      // by memory size
+    by_site       // by call site where the memory is allocated from
   };
 
-  inline size_t count() const {
-    return _count;
-  }
+ private:
+  // All baseline data is stored in this arena
+  Arena*                  _arena;
+
+  // Summary information
+  MallocMemorySnapshot*   _malloc_memory_snapshot;
+  VirtualMemorySnapshot*  _virtual_memory_snapshot;
+
+  size_t               _class_count;
 
-  inline size_t amount() const {
-    return _amount;
-  }
-};
+  // Allocation sites information
+  // Malloc allocation sites
+  LinkedListImpl<MallocSite, ResourceObj::ARENA>
+                       _malloc_sites;
+
+  // All virtual memory allocations
+  LinkedListImpl<ReservedMemoryRegion, ResourceObj::ARENA>
+                       _virtual_memory_allocations;
 
-// baselined virtual memory record aggregated by callsite
-class VMCallsitePointer : public MemPointer {
- private:
-  size_t     _count;              // number of invocation from this callsite
-  size_t     _reserved_amount;    // total reserved amount
-  size_t     _committed_amount;   // total committed amount
+  // Virtual memory allocations by allocation sites, always in by_address
+  // order
+  LinkedListImpl<VirtualMemoryAllocationSite, ResourceObj::ARENA>
+                       _virtual_memory_sites;
+
+  SortingOrder         _malloc_sites_order;
+  SortingOrder         _virtual_memory_sites_order;
+
+  BaselineType         _baseline_type;
 
  public:
-  VMCallsitePointer() {
-    _count = 0;
-    _reserved_amount = 0;
-    _committed_amount = 0;
-  }
-
-  VMCallsitePointer(address pc) : MemPointer(pc) {
-    _count = 0;
-    _reserved_amount = 0;
-    _committed_amount = 0;
-  }
-
-  VMCallsitePointer& operator=(const VMCallsitePointer& p) {
-    MemPointer::operator=(p);
-    _count = p.count();
-    _reserved_amount = p.reserved_amount();
-    _committed_amount = p.committed_amount();
-    return *this;
-  }
-
-  inline void inc(size_t reserved, size_t committed) {
-    _count ++;
-    _reserved_amount += reserved;
-    _committed_amount += committed;
-  }
-
-  inline size_t count() const {
-    return _count;
-  }
-
-  inline size_t reserved_amount() const {
-    return _reserved_amount;
+  // create a memory baseline
+  MemBaseline():
+    _baseline_type(Not_baselined),
+    _class_count(0),
+    _arena(NULL),
+    _malloc_memory_snapshot(NULL),
+    _virtual_memory_snapshot(NULL),
+    _malloc_sites(NULL) {
   }
 
-  inline size_t committed_amount() const {
-    return _committed_amount;
-  }
-};
-
-// maps a memory type flag to readable name
-typedef struct _memType2Name {
-  MEMFLAGS     _flag;
-  const char*  _name;
-} MemType2Name;
-
-
-// This class aggregates malloc'd records by memory type
-class MallocMem VALUE_OBJ_CLASS_SPEC {
- private:
-  MEMFLAGS       _type;
-
-  size_t         _count;
-  size_t         _amount;
-
- public:
-  MallocMem() {
-    _type = mtNone;
-    _count = 0;
-    _amount = 0;
+  ~MemBaseline() {
+    reset();
+    if (_arena != NULL) {
+      delete _arena;
+    }
   }
 
-  MallocMem(MEMFLAGS flags) {
-    assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
-    _type = FLAGS_TO_MEMORY_TYPE(flags);
-    _count = 0;
-    _amount = 0;
-  }
+  bool baseline(bool summaryOnly = true);
 
-  inline void set_type(MEMFLAGS flag) {
-    _type = flag;
-  }
+  BaselineType baseline_type() const { return _baseline_type; }
 
-  inline void clear() {
-    _count = 0;
-    _amount = 0;
-    _type = mtNone;
+  MallocMemorySnapshot* malloc_memory_snapshot() const {
+    return _malloc_memory_snapshot;
   }
 
-  MallocMem& operator=(const MallocMem& m) {
-    assert(_type == m.type(), "different type");
-    _count = m.count();
-    _amount = m.amount();
-    return *this;
+  VirtualMemorySnapshot* virtual_memory_snapshot() const {
+    return _virtual_memory_snapshot;
   }
 
-  inline void inc(size_t amt) {
-    _amount += amt;
-    _count ++;
-  }
+  MallocSiteIterator malloc_sites(SortingOrder order);
+  VirtualMemorySiteIterator virtual_memory_sites(SortingOrder order);
 
-  inline void reduce(size_t amt) {
-    assert(_amount >= amt, "Just check");
-    _amount -= amt;
-  }
-
-  inline void overwrite_counter(size_t count) {
-    _count = count;
+  // Virtual memory allocation iterator always returns in virtual memory
+  // base address order.
+  VirtualMemoryAllocationIterator virtual_memory_allocations() {
+    assert(!_virtual_memory_allocations.is_empty(), "Not detail baseline");
+    return VirtualMemoryAllocationIterator(_virtual_memory_allocations.head());
   }
 
-  inline MEMFLAGS type() const {
-    return _type;
-  }
-
-  inline bool is_type(MEMFLAGS flags) const {
-    return FLAGS_TO_MEMORY_TYPE(flags) == _type;
-  }
-
-  inline size_t count() const {
-    return _count;
+  // Total reserved memory = total malloc'd memory + total reserved virtual
+  // memory
+  size_t total_reserved_memory() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    assert(_virtual_memory_snapshot != NULL, "No virtual memory snapshot");
+    assert(_malloc_memory_snapshot != NULL,  "No malloc memory snapshot");
+    size_t amount = _malloc_memory_snapshot->total() +
+           _virtual_memory_snapshot->total_reserved();
+    return amount;
   }
 
-  inline size_t amount() const {
-    return _amount;
-  }
-};
-
-// This class records live arena's memory usage
-class ArenaMem : public MallocMem {
- public:
-  ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
-  }
-  ArenaMem() { }
-};
-
-// This class aggregates virtual memory by its memory type
-class VMMem VALUE_OBJ_CLASS_SPEC {
- private:
-  MEMFLAGS       _type;
-
-  size_t         _count;
-  size_t         _reserved_amount;
-  size_t         _committed_amount;
-
- public:
-  VMMem() {
-    _type = mtNone;
-    _count = 0;
-    _reserved_amount = 0;
-    _committed_amount = 0;
+  // Total committed memory = total malloc'd memory + total committed
+  // virtual memory
+  size_t total_committed_memory() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    assert(_virtual_memory_snapshot != NULL,
+      "Not a snapshot");
+    size_t amount = _malloc_memory_snapshot->total() +
+           _virtual_memory_snapshot->total_committed();
+    return amount;
   }
 
-  VMMem(MEMFLAGS flags) {
-    assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
-    _type = FLAGS_TO_MEMORY_TYPE(flags);
-    _count = 0;
-    _reserved_amount = 0;
-    _committed_amount = 0;
+  size_t total_arena_memory() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    assert(_malloc_memory_snapshot != NULL, "Not yet baselined");
+    return _malloc_memory_snapshot->total_arena();
   }
 
-  inline void clear() {
-    _type = mtNone;
-    _count = 0;
-    _reserved_amount = 0;
-    _committed_amount = 0;
+  size_t malloc_tracking_overhead() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    return _malloc_memory_snapshot->malloc_overhead()->size();
   }
 
-  inline void set_type(MEMFLAGS flags) {
-    _type = FLAGS_TO_MEMORY_TYPE(flags);
+  const MallocMemory* malloc_memory(MEMFLAGS flag) const {
+    assert(_malloc_memory_snapshot != NULL, "Not a snapshot");
+    return _malloc_memory_snapshot->by_type(flag);
   }
 
-  VMMem& operator=(const VMMem& m) {
-    assert(_type == m.type(), "different type");
-
-    _count = m.count();
-    _reserved_amount = m.reserved_amount();
-    _committed_amount = m.committed_amount();
-    return *this;
+  const VirtualMemory* virtual_memory(MEMFLAGS flag) const {
+    assert(_virtual_memory_snapshot != NULL, "Not a snapshot");
+    return _virtual_memory_snapshot->by_type(flag);
   }
 
 
-  inline MEMFLAGS type() const {
-    return _type;
-  }
-
-  inline bool is_type(MEMFLAGS flags) const {
-    return FLAGS_TO_MEMORY_TYPE(flags) == _type;
-  }
-
-  inline void inc(size_t reserved_amt, size_t committed_amt) {
-    _reserved_amount += reserved_amt;
-    _committed_amount += committed_amt;
-    _count ++;
-  }
-
-  inline size_t count() const {
-    return _count;
-  }
-
-  inline size_t reserved_amount() const {
-    return _reserved_amount;
+  size_t class_count() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    return _class_count;
   }
 
-  inline size_t committed_amount() const {
-    return _committed_amount;
+  size_t thread_count() const {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    assert(_malloc_memory_snapshot != NULL, "Baselined?");
+    return _malloc_memory_snapshot->thread_count();
   }
-};
-
-
-
-#define NUMBER_OF_MEMORY_TYPE    (mt_number_of_types + 1)
-
-class BaselineReporter;
-class BaselineComparisonReporter;
-
-/*
- * This class baselines current memory snapshot.
- * A memory baseline summarizes memory usage by memory type,
- * aggregates memory usage by callsites when detail tracking
- * is on.
- */
-class MemBaseline VALUE_OBJ_CLASS_SPEC {
-  friend class BaselineReporter;
-  friend class BaselineComparisonReporter;
-
- private:
-  // overall summaries
-  size_t        _total_malloced;
-  size_t        _total_vm_reserved;
-  size_t        _total_vm_committed;
-  size_t        _number_of_classes;
-  size_t        _number_of_threads;
-
-  // if it has properly baselined
-  bool          _baselined;
-
-  // we categorize memory into three categories within the memory type
-  MallocMem     _malloc_data[NUMBER_OF_MEMORY_TYPE];
-  VMMem         _vm_data[NUMBER_OF_MEMORY_TYPE];
-  ArenaMem      _arena_data[NUMBER_OF_MEMORY_TYPE];
-
-  // memory records that aggregate memory usage by callsites.
-  // only available when detail tracking is on.
-  MemPointerArray*  _malloc_cs;
-  MemPointerArray*  _vm_cs;
-  // virtual memory map
-  MemPointerArray*  _vm_map;
-
- private:
-  static MemType2Name  MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
-
- private:
-  // should not use copy constructor
-  MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
-
-  // check and block at a safepoint
-  static inline void check_safepoint(JavaThread* thr);
-
- public:
-  // create a memory baseline
-  MemBaseline();
-
-  ~MemBaseline();
-
-  inline bool baselined() const {
-    return _baselined;
-  }
-
-  MemBaseline& operator=(const MemBaseline& other);
 
   // reset the baseline for reuse
-  void clear();
-
-  // baseline the snapshot
-  bool baseline(MemSnapshot& snapshot, bool summary_only = true);
-
-  bool baseline(const MemPointerArray* malloc_records,
-                const MemPointerArray* vm_records,
-                bool summary_only = true);
+  void reset() {
+    _baseline_type = Not_baselined;
+    _malloc_memory_snapshot = NULL;
+    _virtual_memory_snapshot = NULL;
+    _class_count  = 0;
 
-  // total malloc'd memory of specified memory type
-  inline size_t malloc_amount(MEMFLAGS flag) const {
-    return _malloc_data[flag2index(flag)].amount();
-  }
-  // number of malloc'd memory blocks of specified memory type
-  inline size_t malloc_count(MEMFLAGS flag) const {
-    return _malloc_data[flag2index(flag)].count();
-  }
-  // total memory used by arenas of specified memory type
-  inline size_t arena_amount(MEMFLAGS flag) const {
-    return _arena_data[flag2index(flag)].amount();
-  }
-  // number of arenas of specified memory type
-  inline size_t arena_count(MEMFLAGS flag) const {
-    return _arena_data[flag2index(flag)].count();
-  }
-  // total reserved memory of specified memory type
-  inline size_t reserved_amount(MEMFLAGS flag) const {
-    return _vm_data[flag2index(flag)].reserved_amount();
-  }
-  // total committed memory of specified memory type
-  inline size_t committed_amount(MEMFLAGS flag) const {
-    return _vm_data[flag2index(flag)].committed_amount();
-  }
-  // total memory (malloc'd + mmap'd + arena) of specified
-  // memory type
-  inline size_t total_amount(MEMFLAGS flag) const {
-    int index = flag2index(flag);
-    return _malloc_data[index].amount() +
-           _vm_data[index].reserved_amount() +
-           _arena_data[index].amount();
+    _malloc_sites = NULL;
+    _virtual_memory_sites = NULL;
+    _virtual_memory_allocations = NULL;
+
+    if (_arena != NULL) {
+      _arena->destruct_contents();
+    }
   }
 
-  /* overall summaries */
+ private:
+  // Baseline summary information
+  bool baseline_summary();
 
-  // total malloc'd memory in snapshot
-  inline size_t total_malloc_amount() const {
-    return _total_malloced;
-  }
-  // total mmap'd memory in snapshot
-  inline size_t total_reserved_amount() const {
-    return _total_vm_reserved;
-  }
-  // total committed memory in snapshot
-  inline size_t total_committed_amount() const {
-    return _total_vm_committed;
-  }
-  // number of loaded classes
-  inline size_t number_of_classes() const {
-    return _number_of_classes;
-  }
-  // number of running threads
-  inline size_t number_of_threads() const {
-    return _number_of_threads;
-  }
-  // lookup human readable name of a memory type
-  static const char* type2name(MEMFLAGS type);
+  // Baseline allocation sites (detail tracking only)
+  bool baseline_allocation_sites();
+
+  // Aggregate virtual memory allocation by allocation sites
+  bool aggregate_virtual_memory_allocation_sites();
 
- private:
-  // convert memory flag to the index to mapping table
-  int         flag2index(MEMFLAGS flag) const;
-
-  // reset baseline values
-  void reset();
-
-  // summarize the records in global snapshot
-  bool baseline_malloc_summary(const MemPointerArray* malloc_records);
-  bool baseline_vm_summary(const MemPointerArray* vm_records);
-  bool baseline_malloc_details(const MemPointerArray* malloc_records);
-  bool baseline_vm_details(const MemPointerArray* vm_records);
+  Arena* arena() { return _arena; }
 
-  // print a line of malloc'd memory aggregated by callsite
-  void print_malloc_callsite(outputStream* st, address pc, size_t size,
-    size_t count, int diff_amt, int diff_count) const;
-  // print a line of mmap'd memory aggregated by callsite
-  void print_vm_callsite(outputStream* st, address pc, size_t rsz,
-    size_t csz, int diff_rsz, int diff_csz) const;
+  // Sorting allocation sites in different orders
+  // Sort allocation sites in size order
+  void malloc_sites_to_size_order();
+  // Sort allocation sites in call site address order
+  void malloc_sites_to_allocation_site_order();
 
-  // sorting functions for raw records
-  static int malloc_sort_by_pc(const void* p1, const void* p2);
-  static int malloc_sort_by_addr(const void* p1, const void* p2);
-
- private:
-  // sorting functions for baselined records
-  static int bl_malloc_sort_by_size(const void* p1, const void* p2);
-  static int bl_vm_sort_by_size(const void* p1, const void* p2);
-  static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
-  static int bl_vm_sort_by_pc(const void* p1, const void* p2);
+  // Sort allocation sites in reserved size order
+  void virtual_memory_sites_to_size_order();
+  // Sort allocation sites in call site address order
+  void virtual_memory_sites_to_reservation_site_order();
 };
 
+#endif // INCLUDE_NMT
 
 #endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP