Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/services/memBaseline.cpp
32285 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/23#include "precompiled.hpp"2425#include "memory/allocation.hpp"26#include "runtime/safepoint.hpp"27#include "runtime/thread.inline.hpp"28#include "services/memBaseline.hpp"29#include "services/memTracker.hpp"3031/*32* Sizes are sorted in descenting order for reporting33*/34int compare_malloc_size(const MallocSite& s1, const MallocSite& s2) {35if (s1.size() == s2.size()) {36return 0;37} else if (s1.size() > s2.size()) {38return -1;39} else {40return 1;41}42}434445int compare_virtual_memory_size(const VirtualMemoryAllocationSite& s1,46const VirtualMemoryAllocationSite& s2) {47if (s1.reserved() == s2.reserved()) {48return 0;49} else if (s1.reserved() > s2.reserved()) {50return -1;51} else {52return 1;53}54}5556// Sort into allocation site addresses order for baseline comparison57int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) {58return s1.call_stack()->compare(*s2.call_stack());59}6061// Sort into allocation site addresses and memory type order for baseline comparison62int compare_malloc_site_and_type(const MallocSite& s1, const MallocSite& s2) {63int res = compare_malloc_site(s1, s2);64if (res == 0) {65res = (int)(s1.flag() - s2.flag());66}6768return res;69}7071int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,72const VirtualMemoryAllocationSite& s2) {73return s1.call_stack()->compare(*s2.call_stack());74}7576/*77* Walker to walk malloc allocation site table78*/79class MallocAllocationSiteWalker : public MallocSiteWalker {80private:81SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;82size_t _count;8384// Entries in MallocSiteTable with size = 0 and count = 0,85// when the malloc site is not longer there.86public:87MallocAllocationSiteWalker() : _count(0) { }8889inline size_t count() const { return _count; }9091LinkedList<MallocSite>* malloc_sites() {92return &_malloc_sites;93}9495bool do_malloc_site(const MallocSite* site) {96if (site->size() >= MemBaseline::SIZE_THRESHOLD) {97if (_malloc_sites.add(*site) != NULL) {98_count++;99return true;100} else {101return false; // OOM102}103} else {104// malloc site does not meet threshold, ignore and continue105return true;106}107}108};109110// Compare virtual memory region's base address111int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) {112return r1.compare(r2);113}114115// Walk all virtual memory regions for baselining116class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {117private:118SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>119_virtual_memory_regions;120size_t _count;121122public:123VirtualMemoryAllocationWalker() : _count(0) { }124125bool do_allocation_site(const ReservedMemoryRegion* rgn) {126if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) {127if (_virtual_memory_regions.add(*rgn) != NULL) {128_count ++;129return true;130} else {131return false;132}133}134return true;135}136137LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() {138return &_virtual_memory_regions;139}140};141142143bool MemBaseline::baseline_summary() {144MallocMemorySummary::snapshot(&_malloc_memory_snapshot);145VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);146return true;147}148149bool MemBaseline::baseline_allocation_sites() {150// Malloc allocation sites151MallocAllocationSiteWalker malloc_walker;152if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {153return false;154}155156_malloc_sites.move(malloc_walker.malloc_sites());157// The malloc sites are collected in size order158_malloc_sites_order = by_size;159160// Virtual memory allocation sites161VirtualMemoryAllocationWalker virtual_memory_walker;162if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {163return false;164}165166// Virtual memory allocations are collected in call stack order167_virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());168169if (!aggregate_virtual_memory_allocation_sites()) {170return false;171}172// Virtual memory allocation sites are aggregrated in call stack order173_virtual_memory_sites_order = by_address;174175return true;176}177178bool MemBaseline::baseline(bool summaryOnly) {179reset();180181_class_count = InstanceKlass::number_of_instance_classes();182183if (!baseline_summary()) {184return false;185}186187_baseline_type = Summary_baselined;188189// baseline details190if (!summaryOnly &&191MemTracker::tracking_level() == NMT_detail) {192baseline_allocation_sites();193_baseline_type = Detail_baselined;194}195196return true;197}198199int compare_allocation_site(const VirtualMemoryAllocationSite& s1,200const VirtualMemoryAllocationSite& s2) {201return s1.call_stack()->compare(*s2.call_stack());202}203204bool MemBaseline::aggregate_virtual_memory_allocation_sites() {205SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;206207VirtualMemoryAllocationIterator itr = virtual_memory_allocations();208const ReservedMemoryRegion* rgn;209VirtualMemoryAllocationSite* site;210while ((rgn = itr.next()) != NULL) {211VirtualMemoryAllocationSite tmp(*rgn->call_stack(), rgn->flag());212site = allocation_sites.find(tmp);213if (site == NULL) {214LinkedListNode<VirtualMemoryAllocationSite>* node =215allocation_sites.add(tmp);216if (node == NULL) return false;217site = node->data();218}219site->reserve_memory(rgn->size());220site->commit_memory(rgn->committed_size());221}222223_virtual_memory_sites.move(&allocation_sites);224return true;225}226227MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {228assert(!_malloc_sites.is_empty(), "Not detail baseline");229switch(order) {230case by_size:231malloc_sites_to_size_order();232break;233case by_site:234malloc_sites_to_allocation_site_order();235break;236case by_site_and_type:237malloc_sites_to_allocation_site_and_type_order();238break;239case by_address:240default:241ShouldNotReachHere();242}243return MallocSiteIterator(_malloc_sites.head());244}245246VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {247assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");248switch(order) {249case by_size:250virtual_memory_sites_to_size_order();251break;252case by_site:253virtual_memory_sites_to_reservation_site_order();254break;255case by_address:256default:257ShouldNotReachHere();258}259return VirtualMemorySiteIterator(_virtual_memory_sites.head());260}261262263// Sorting allocations sites in different orders264void MemBaseline::malloc_sites_to_size_order() {265if (_malloc_sites_order != by_size) {266SortedLinkedList<MallocSite, compare_malloc_size> tmp;267268// Add malloc sites to sorted linked list to sort into size order269tmp.move(&_malloc_sites);270_malloc_sites.set_head(tmp.head());271tmp.set_head(NULL);272_malloc_sites_order = by_size;273}274}275276void MemBaseline::malloc_sites_to_allocation_site_order() {277if (_malloc_sites_order != by_site && _malloc_sites_order != by_site_and_type) {278SortedLinkedList<MallocSite, compare_malloc_site> tmp;279// Add malloc sites to sorted linked list to sort into site (address) order280tmp.move(&_malloc_sites);281_malloc_sites.set_head(tmp.head());282tmp.set_head(NULL);283_malloc_sites_order = by_site;284}285}286287void MemBaseline::malloc_sites_to_allocation_site_and_type_order() {288if (_malloc_sites_order != by_site_and_type) {289SortedLinkedList<MallocSite, compare_malloc_site_and_type> tmp;290// Add malloc sites to sorted linked list to sort into site (address) order291tmp.move(&_malloc_sites);292_malloc_sites.set_head(tmp.head());293tmp.set_head(NULL);294_malloc_sites_order = by_site_and_type;295}296}297298void MemBaseline::virtual_memory_sites_to_size_order() {299if (_virtual_memory_sites_order != by_size) {300SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;301302tmp.move(&_virtual_memory_sites);303304_virtual_memory_sites.set_head(tmp.head());305tmp.set_head(NULL);306_virtual_memory_sites_order = by_size;307}308}309310void MemBaseline::virtual_memory_sites_to_reservation_site_order() {311if (_virtual_memory_sites_order != by_size) {312SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;313314tmp.move(&_virtual_memory_sites);315316_virtual_memory_sites.set_head(tmp.head());317tmp.set_head(NULL);318319_virtual_memory_sites_order = by_size;320}321}322323324325