Path: blob/master/runtime/gc_trace_standard/TgcFreeListSummary.cpp
5985 views
1/*******************************************************************************2* Copyright (c) 1991, 2019 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/2223#include "j9.h"24#include "j9cfg.h"25#include "mmhook.h"26#include "j9port.h"27#include "modronopt.h"28#include "ModronAssertions.h"2930#include "TgcFreeListSummary.hpp"3132#include "GCExtensions.hpp"33#include "HeapStats.hpp"34#include "TgcExtensions.hpp"3536#include "EnvironmentBase.hpp"37#include "Heap.hpp"38#include "HeapLinkedFreeHeader.hpp"39#include "HeapMemoryPoolIterator.hpp"40#include "MemoryPool.hpp"4142#define STAT_ELEMENTS 2243#define FIRST_ELEMENT_THRESHOLD 10244445/*46* Free List Summary is organized as a array of counters. Each counter represents number of holes in pool with size in particular range.47* First element represents number of holes smaller then FIRST_ELEMENT_THRESHOLD bytes (but larger then dark matter threshold - 512 bytes default)48* Second element represents number of holes smaller then 2 * FIRST_ELEMENT_THRESHOLD but larger then FIRST_ELEMENT_THRESHOLD.49* Each next element has a doubled threshold, except last one which represents number of holes larger then previous threshold.50* The table of thresholds for FIRST_ELEMENT_THRESHOLD = 1024 and number of elements = 22 is below:51*52* 1 <102453* 2 <204854* 3 <409655* 4 <819256* 5 <1638457* 6 <3276858* 7 <6553659* 8 <13107260* 9 <26214461* 10 <52428862* 11 <104857663* 12 <209715264* 13 <419430465* 14 <838860866* 15 <1677721667* 16 <3355443268* 17 <6710886469* 18 <13421772870* 19 <26843545671* 20 <53687091272* 21 <107374182473* 22 >=107374182474*75*/7677/*78* Increment the counter responsible for size in range79* @param size Size of hole we want to add to count80* @param array Pointer to Free List Summary array81* @param elements Number of elements in Free List Summary array82*/83static void84addSizeToSummary(UDATA size, UDATA *array, UDATA elements)85{86UDATA i;87UDATA n = FIRST_ELEMENT_THRESHOLD;88for (i = 0; i < elements - 1; i++) {89if (size < n) {90array[i] += 1;91return;92}93n = n * 2;94}95array[elements - 1] += 1;96}9798/*99* Calculate Free List Summary for Memory Pool. Return size of Largest hole discovered in pool100* @param env thread information101* @param pool Memory pool to calculate summary102* @param statsArray Pointer to Free List Summary array103* @param elements Number of elements in Free List Summary array104* @return Size of largest hole discovered in pool105*/106static UDATA107calcSummaryForMemoryPool(MM_EnvironmentBase *env, MM_MemoryPool *pool, UDATA *statsArray, UDATA elements)108{109UDATA i;110UDATA largest = 0;111112for (i = 0; i < elements; i++) {113statsArray[i] = 0;114}115116MM_HeapLinkedFreeHeader *currentFreeEntry = (MM_HeapLinkedFreeHeader *)pool->getFirstFreeStartingAddr(env);117while(currentFreeEntry) {118UDATA size = currentFreeEntry->getSize();119if (size > largest) {120largest = size;121}122addSizeToSummary(size, statsArray, elements);123currentFreeEntry = (MM_HeapLinkedFreeHeader *)pool->getNextFreeStartingAddr(env, currentFreeEntry);124}125126return largest;127}128129/*130* Walk all MPAOLs in heap, calculate Free List Summary and print it.131* @param env thread information132* @param verboseEvent Event description iv verbose form133*/134static void135calcAndPrintFreeListSummary(MM_EnvironmentBase *env, const char *verboseEvent)136{137MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);138MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);139MM_MemoryPool *memoryPool = NULL;140MM_HeapMemoryPoolIterator poolIterator(env, extensions->heap);141142UDATA statsArray[STAT_ELEMENTS];143UDATA statLargest = 0;144UDATA i;145146tgcExtensions->printf("\n<free_list_summary reason=\"%s\">\n", verboseEvent);147while(NULL != (memoryPool = (MM_MemoryPool *)poolIterator.nextPool())) {148statLargest = calcSummaryForMemoryPool(env, memoryPool, statsArray, STAT_ELEMENTS);149tgcExtensions->printf("<memory_pool address=\"%p\" name=\"%s\" largest=\"%d\">", memoryPool, memoryPool->getPoolName(), statLargest);150for (i = 0; i < STAT_ELEMENTS; i++) {151tgcExtensions->printf(" %d", statsArray[i]);152}153tgcExtensions->printf(" </memory_pool>\n");154}155tgcExtensions->printf("</free_list_summary>\n");156}157158/*159* Handle for J9HOOK_MM_GLOBAL_GC_START event160*/161static void162tgcHookFreeListSummaryStart(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)163{164MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;165MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->currentThread);166calcAndPrintFreeListSummary(env, "Global GC Start");167}168169/*170* Handle for J9HOOK_MM_GLOBAL_GC_END event171*/172static void173tgcHookFreeListSummaryEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)174{175MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;176MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->currentThread);177calcAndPrintFreeListSummary(env, "Global GC End");178}179180/*181* Initialization for Free List Summary request182*/183bool184tgcFreeListSummaryInitialize(J9JavaVM *javaVM)185{186MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);187bool result = true;188189J9HookInterface** hooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);190(*hooks)->J9HookRegisterWithCallSite(hooks, J9HOOK_MM_OMR_GLOBAL_GC_START, tgcHookFreeListSummaryStart, OMR_GET_CALLSITE(), javaVM);191(*hooks)->J9HookRegisterWithCallSite(hooks, J9HOOK_MM_OMR_GLOBAL_GC_END, tgcHookFreeListSummaryEnd, OMR_GET_CALLSITE(), javaVM);192193return result;194}195196197