Path: blob/master/runtime/gc_trace/TgcNuma.cpp
5985 views
1/*******************************************************************************2* Copyright (c) 1991, 2020 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 "j9port.h"26#include "Tgc.hpp"27#include "mmhook.h"2829#if defined(J9VM_GC_VLHGC)30#include "EnvironmentBase.hpp"31#include "GCExtensions.hpp"32#include "Heap.hpp"33#include "HeapRegionIterator.hpp"34#include "HeapRegionDescriptor.hpp"35#include "TgcExtensions.hpp"36#include "VMThreadListIterator.hpp"3738/**39* Report NUMA statistics prior to a collection40*/41static void42tgcHookReportNumaStatistics(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)43{44MM_GlobalGCStartEvent* event = (MM_GlobalGCStartEvent*)eventData;45J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;46J9JavaVM *javaVM = vmThread->javaVM;47MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);48MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);49TgcNumaExtensions *numaExtensions = &tgcExtensions->_numa;5051/*52* Initialize the extensions if they haven't been initialized yet53*/54if (NULL == numaExtensions->nodeData) {55UDATA maxNode = extensions->_numaManager.getMaximumNodeNumber();56UDATA dataSizeInBytes = (maxNode + 1) * sizeof(TgcNumaExtensions::NumaNodeData);57MM_Forge *forge = extensions->getForge();5859numaExtensions->numaNodes = maxNode;60numaExtensions->nodeData = (TgcNumaExtensions::NumaNodeData*)forge->allocate(dataSizeInBytes, MM_AllocationCategory::DIAGNOSTIC, J9_GET_CALLSITE());61}6263if (NULL != numaExtensions->nodeData) {64memset(numaExtensions->nodeData, 0, (numaExtensions->numaNodes + 1) * sizeof(TgcNumaExtensions::NumaNodeData));6566/*67* Count threads68*/69GC_VMThreadListIterator threadIterator(vmThread);70J9VMThread * walkThread = NULL;71while (NULL != (walkThread = threadIterator.nextVMThread())) {72MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(walkThread->omrVMThread);7374UDATA threadNode = 0;75UDATA nodeCount = 1;76if ((0 != omrthread_numa_get_node_affinity(walkThread->osThread, &threadNode, &nodeCount)) || (0 == nodeCount)) {77threadNode = 0;78}79numaExtensions->nodeData[threadNode].threads += 1;8081if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {82numaExtensions->nodeData[threadNode].gcThreads += 1;83}84}8586/*87* Count regions88*/89MM_HeapRegionManager *regionManager = extensions->heap->getHeapRegionManager();90GC_HeapRegionIterator regionIterator(regionManager, MM_HeapRegionDescriptor::MANAGED);91MM_HeapRegionDescriptor *region = NULL;92while (NULL != (region = regionIterator.nextRegion())) {93UDATA regionNode = extensions->_numaManager.getJ9NodeNumber(region->getNumaNode());94if (region->isCommitted()) {95numaExtensions->nodeData[regionNode].committedRegions += 1;96}97if (region->getRegionType() == MM_HeapRegionDescriptor::FREE) {98numaExtensions->nodeData[regionNode].freeRegions += 1;99}100numaExtensions->nodeData[regionNode].totalRegions += 1;101}102103/*104* Report results105*/106for (UDATA i = 0; i <= numaExtensions->numaNodes; i++) {107tgcExtensions->printf(108"NUMA node %zu has %zu regions (%zu committed, %zu free) %zu threads (%zu GC threads)\n",109i,110numaExtensions->nodeData[i].totalRegions,111numaExtensions->nodeData[i].committedRegions,112numaExtensions->nodeData[i].freeRegions,113numaExtensions->nodeData[i].threads,114numaExtensions->nodeData[i].gcThreads);115}116}117}118119120/**121* Initialize NUMA tgc tracing.122* Attaches hooks to the appropriate functions handling events used by NUMA tgc tracing.123*/124bool125tgcNumaInitialize(J9JavaVM *javaVM)126{127MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);128MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);129bool result = true;130131tgcExtensions->_numa.numaNodes = 0;132tgcExtensions->_numa.nodeData = NULL;133134J9HookInterface** hooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);135(*hooks)->J9HookRegisterWithCallSite(hooks, J9HOOK_MM_OMR_GLOBAL_GC_START, tgcHookReportNumaStatistics, OMR_GET_CALLSITE(), NULL);136(*hooks)->J9HookRegisterWithCallSite(hooks, J9HOOK_MM_OMR_LOCAL_GC_START, tgcHookReportNumaStatistics, OMR_GET_CALLSITE(), NULL);137(*hooks)->J9HookRegisterWithCallSite(hooks, J9HOOK_MM_OMR_LOCAL_GC_END, tgcHookReportNumaStatistics, OMR_GET_CALLSITE(), NULL);138139return result;140}141142#endif /* J9VM_GC_VLHGC */143144145