src/share/vm/services/memBaseline.cpp

Wed, 31 Jan 2018 19:24:57 -0500

author
dbuck
date
Wed, 31 Jan 2018 19:24:57 -0500
changeset 9289
427b2fb1944f
parent 9054
db49d511817a
child 9122
024be04bb151
child 9778
bf6ea7319424
permissions
-rw-r--r--

8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed

     1 /*
     2  * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    24 #include "precompiled.hpp"
    26 #include "memory/allocation.hpp"
    27 #include "runtime/safepoint.hpp"
    28 #include "runtime/thread.inline.hpp"
    29 #include "services/memBaseline.hpp"
    30 #include "services/memTracker.hpp"
    32 /*
    33  * Sizes are sorted in descenting order for reporting
    34  */
    35 int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) {
    36   if (s1.size() == s2.size()) {
    37     return 0;
    38   } else if (s1.size() > s2.size()) {
    39     return -1;
    40   } else {
    41     return 1;
    42   }
    43 }
    46 int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1,
    47   const VirtualMemoryAllocationSite& s2) {
    48   if (s1.reserved() == s2.reserved()) {
    49     return 0;
    50   } else if (s1.reserved() > s2.reserved()) {
    51     return -1;
    52   } else {
    53     return 1;
    54   }
    55 }
    57 // Sort into allocation site addresses order for baseline comparison
    58 int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) {
    59   return s1.call_stack()->compare(*s2.call_stack());
    60 }
    62 // Sort into allocation site addresses and memory type order for baseline comparison
    63 int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) {
    64   int res = compare_malloc_site(s1, s2);
    65   if (res == 0) {
    66     res = (int)(s1.flags() - s2.flags());
    67   }
    69   return res;
    70 }
    72 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,
    73   const VirtualMemoryAllocationSite& s2) {
    74   return s1.call_stack()->compare(*s2.call_stack());
    75 }
    77 /*
    78  * Walker to walk malloc allocation site table
    79  */
    80 class MallocAllocationSiteWalker : public MallocSiteWalker {
    81  private:
    82   SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;
    83   size_t         _count;
    85   // Entries in MallocSiteTable with size = 0 and count = 0,
    86   // when the malloc site is not longer there.
    87  public:
    88   MallocAllocationSiteWalker() : _count(0) { }
    90   inline size_t count() const { return _count; }
    92   LinkedList<MallocSite>* malloc_sites() {
    93     return &_malloc_sites;
    94   }
    96   bool do_malloc_site(const MallocSite* site) {
    97     if (site->size() >= MemBaseline::SIZE_THRESHOLD) {
    98       if (_malloc_sites.add(*site) != NULL) {
    99         _count++;
   100         return true;
   101       } else {
   102         return false;  // OOM
   103       }
   104     } else {
   105       // malloc site does not meet threshold, ignore and continue
   106       return true;
   107     }
   108   }
   109 };
   111 // Compare virtual memory region's base address
   112 int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {
   113   return r1.compare(r2);
   114 }
   116 // Walk all virtual memory regions for baselining
   117 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
   118  private:
   119   SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>
   120                 _virtual_memory_regions;
   121   size_t        _count;
   123  public:
   124   VirtualMemoryAllocationWalker() : _count(0) { }
   126   bool do_allocation_site(const ReservedMemoryRegion* rgn)  {
   127     if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) {
   128       if (_virtual_memory_regions.add(*rgn) != NULL) {
   129         _count ++;
   130         return true;
   131       } else {
   132         return false;
   133       }
   134     }
   135     return true;
   136   }
   138   LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {
   139     return &_virtual_memory_regions;
   140   }
   141 };
   144 bool MemBaseline::baseline_summary() {
   145   MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
   146   VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
   147   return true;
   148 }
   150 bool MemBaseline::baseline_allocation_sites() {
   151   // Malloc allocation sites
   152   MallocAllocationSiteWalker malloc_walker;
   153   if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {
   154     return false;
   155   }
   157   _malloc_sites.move(malloc_walker.malloc_sites());
   158   // The malloc sites are collected in size order
   159   _malloc_sites_order = by_size;
   161   // Virtual memory allocation sites
   162   VirtualMemoryAllocationWalker virtual_memory_walker;
   163   if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {
   164     return false;
   165   }
   167   // Virtual memory allocations are collected in call stack order
   168   _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
   170   if (!aggregate_virtual_memory_allocation_sites()) {
   171     return false;
   172   }
   173   // Virtual memory allocation sites are aggregrated in call stack order
   174   _virtual_memory_sites_order = by_address;
   176   return true;
   177 }
   179 bool MemBaseline::baseline(bool summaryOnly) {
   180   reset();
   182   _class_count = InstanceKlass::number_of_instance_classes();
   184   if (!baseline_summary()) {
   185     return false;
   186   }
   188   _baseline_type = Summary_baselined;
   190   // baseline details
   191   if (!summaryOnly &&
   192       MemTracker::tracking_level() == NMT_detail) {
   193     baseline_allocation_sites();
   194     _baseline_type = Detail_baselined;
   195   }
   197   return true;
   198 }
   200 int compare_allocation_site(const VirtualMemoryAllocationSite& s1,
   201   const VirtualMemoryAllocationSite& s2) {
   202   return s1.call_stack()->compare(*s2.call_stack());
   203 }
   205 bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
   206   SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
   208   VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
   209   const ReservedMemoryRegion* rgn;
   210   VirtualMemoryAllocationSite* site;
   211   while ((rgn = itr.next()) != NULL) {
   212     VirtualMemoryAllocationSite tmp(*rgn->call_stack());
   213     site = allocation_sites.find(tmp);
   214     if (site == NULL) {
   215       LinkedListNode<VirtualMemoryAllocationSite>* node =
   216         allocation_sites.add(tmp);
   217       if (node == NULL) return false;
   218       site = node->data();
   219     }
   220     site->reserve_memory(rgn->size());
   221     site->commit_memory(rgn->committed_size());
   222   }
   224   _virtual_memory_sites.move(&allocation_sites);
   225   return true;
   226 }
   228 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
   229   assert(!_malloc_sites.is_empty(), "Not detail baseline");
   230   switch(order) {
   231     case by_size:
   232       malloc_sites_to_size_order();
   233       break;
   234     case by_site:
   235       malloc_sites_to_allocation_site_order();
   236       break;
   237     case by_site_and_type:
   238       malloc_sites_to_allocation_site_and_type_order();
   239       break;
   240     case by_address:
   241     default:
   242       ShouldNotReachHere();
   243   }
   244   return MallocSiteIterator(_malloc_sites.head());
   245 }
   247 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {
   248   assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");
   249   switch(order) {
   250     case by_size:
   251       virtual_memory_sites_to_size_order();
   252       break;
   253     case by_site:
   254       virtual_memory_sites_to_reservation_site_order();
   255       break;
   256     case by_address:
   257     default:
   258       ShouldNotReachHere();
   259   }
   260   return VirtualMemorySiteIterator(_virtual_memory_sites.head());
   261 }
   264 // Sorting allocations sites in different orders
   265 void MemBaseline::malloc_sites_to_size_order() {
   266   if (_malloc_sites_order != by_size) {
   267     SortedLinkedList<MallocSite, compare_malloc_size> tmp;
   269     // Add malloc sites to sorted linked list to sort into size order
   270     tmp.move(&_malloc_sites);
   271     _malloc_sites.set_head(tmp.head());
   272     tmp.set_head(NULL);
   273     _malloc_sites_order = by_size;
   274   }
   275 }
   277 void MemBaseline::malloc_sites_to_allocation_site_order() {
   278   if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) {
   279     SortedLinkedList<MallocSite, compare_malloc_site> tmp;
   280     // Add malloc sites to sorted linked list to sort into site (address) order
   281     tmp.move(&_malloc_sites);
   282     _malloc_sites.set_head(tmp.head());
   283     tmp.set_head(NULL);
   284     _malloc_sites_order = by_site;
   285   }
   286 }
   288 void MemBaseline::malloc_sites_to_allocation_site_and_type_order() {
   289   if (_malloc_sites_order != by_site_and_type) {
   290     SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp;
   291     // Add malloc sites to sorted linked list to sort into site (address) order
   292     tmp.move(&_malloc_sites);
   293     _malloc_sites.set_head(tmp.head());
   294     tmp.set_head(NULL);
   295     _malloc_sites_order = by_site_and_type;
   296   }
   297 }
   299 void MemBaseline::virtual_memory_sites_to_size_order() {
   300   if (_virtual_memory_sites_order != by_size) {
   301     SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
   303     tmp.move(&_virtual_memory_sites);
   305     _virtual_memory_sites.set_head(tmp.head());
   306     tmp.set_head(NULL);
   307     _virtual_memory_sites_order = by_size;
   308   }
   309 }
   311 void MemBaseline::virtual_memory_sites_to_reservation_site_order() {
   312   if (_virtual_memory_sites_order != by_size) {
   313     SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;
   315     tmp.move(&_virtual_memory_sites);
   317     _virtual_memory_sites.set_head(tmp.head());
   318     tmp.set_head(NULL);
   320     _virtual_memory_sites_order = by_size;
   321   }
   322 }

mercurial