Path: blob/master/runtime/gc_trace/TgcDump.cpp
5985 views
/*******************************************************************************1* Copyright (c) 1991, 2019 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "j9.h"23#include "j9cfg.h"24#include "mmhook.h"25#include "j9port.h"26#include "modronopt.h"27#include "Tgc.hpp"28#include "HeapIteratorAPI.h"2930#include "GCExtensions.hpp"31#include "TgcExtensions.hpp"3233static jvmtiIterationControl dump_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData);34static jvmtiIterationControl dump_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData);35static jvmtiIterationControl dump_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData);36static jvmtiIterationControl dump_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData);3738typedef struct DumpObjectsIteratorCallbackUserData {39bool previousObjectWasFreeSpace; /* was the previous object free space or a live object? */40UDATA gcCount; /* GC identifier */41} DumpObjectsIteratorCallbackUserData;424344/**45* @todo Provide function documentation46*/47static void48tgcHookGlobalGcSweepEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)49{50MM_SweepEndEvent* event = (MM_SweepEndEvent*)eventData;51J9VMThread *vmThread = static_cast<J9VMThread *>(event->currentThread->_language_vmthread);52J9JavaVM* javaVM = vmThread->javaVM;53MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);54MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);5556UDATA gcCount = 0;5758if (extensions->isStandardGC() || extensions->isMetronomeGC()) {59#if defined(J9VM_GC_MODRON_STANDARD) || defined(J9VM_GC_REALTIME)60gcCount = extensions->globalGCStats.gcCount;61if (extensions->isStandardGC()) {62#if defined(J9VM_GC_MODRON_SCAVENGER)63gcCount += extensions->scavengerStats._gcCount;64#endif /* J9VM_GC_MODRON_SCAVENGER */65}66#endif /* J9VM_GC_MODRON_STANDARD || J9VM_GC_REALTIME */67}68if (extensions->isVLHGC()) {69#if defined(J9VM_GC_VLHGC)70gcCount += extensions->globalVLHGCStats.gcCount;71#endif /* J9VM_GC_VLHGC */72}7374tgcExtensions->printf("<GC(%zu) Dumping Middleware Heap free blocks\n", gcCount);7576DumpObjectsIteratorCallbackUserData iteratorData;77iteratorData.gcCount = gcCount;78iteratorData.previousObjectWasFreeSpace = false;79javaVM->memoryManagerFunctions->j9mm_iterate_heaps(javaVM, javaVM->portLibrary, 0, dump_heapIteratorCallback, &iteratorData);80}8182static jvmtiIterationControl83dump_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData)84{85vm->memoryManagerFunctions->j9mm_iterate_spaces(vm, vm->portLibrary, heapDesc, 0, dump_spaceIteratorCallback, userData);86return JVMTI_ITERATION_CONTINUE;87}8889static jvmtiIterationControl90dump_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData)91{92vm->memoryManagerFunctions->j9mm_iterate_regions(vm, vm->portLibrary, spaceDesc, 0, dump_regionIteratorCallback, userData);93return JVMTI_ITERATION_CONTINUE;94}9596static jvmtiIterationControl97dump_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData)98{99DumpObjectsIteratorCallbackUserData* castUserData = (DumpObjectsIteratorCallbackUserData*)userData;100MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vm);101102castUserData->previousObjectWasFreeSpace = false;103104vm->memoryManagerFunctions->j9mm_iterate_region_objects(vm, vm->portLibrary, regionDesc, j9mm_iterator_flag_include_holes, dump_objectIteratorCallback, castUserData);105106/* If the last object in the region was free space, the line was not terminated */107if (castUserData->previousObjectWasFreeSpace) {108tgcExtensions->printf(">\n");109}110111return JVMTI_ITERATION_CONTINUE;112}113114static jvmtiIterationControl115dump_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData)116{117DumpObjectsIteratorCallbackUserData* castUserData = (DumpObjectsIteratorCallbackUserData*)userData;118bool isFreeSpace = false;119UDATA freeSpaceByteSize = 0;120MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vm);121122/* Determine whether or not the object is dead, and get its size. Since the object heap iterator123* doesn't consult the mark map, a "live" object may actually be a dead object in a chunk that wasn't124* large enough to make the free list.125*/126127if (FALSE == objectDesc->isObject) {128isFreeSpace = true;129freeSpaceByteSize = objectDesc->size;130} else if (!(vm->memoryManagerFunctions->j9gc_ext_is_marked(vm, objectDesc->object))) {131isFreeSpace = true;132freeSpaceByteSize = objectDesc->size;133}134135/* Print the next object after free space, and in any case, terminate the line */136if (castUserData->previousObjectWasFreeSpace) {137if (!isFreeSpace) {138tgcExtensions->printf(" -- x%p ", objectDesc->size);139tgcPrintClass(vm, J9GC_J9OBJECT_CLAZZ_VM(objectDesc->object, vm));140}141tgcExtensions->printf(">\n");142}143144if (isFreeSpace) {145tgcExtensions->printf("<GC(%zu) %p freelen=x%p", castUserData->gcCount, objectDesc->id, freeSpaceByteSize);146}147148castUserData->previousObjectWasFreeSpace = isFreeSpace;149150return JVMTI_ITERATION_CONTINUE;151}152153/**154* @todo Provide function documentation155*/156bool157tgcDumpInitialize(J9JavaVM *javaVM)158{159MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);160bool result = true;161162J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);163(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_END, tgcHookGlobalGcSweepEnd, OMR_GET_CALLSITE(), NULL);164165return result;166}167168169