Path: blob/master/runtime/gc_trace/TgcTerse.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 "j9port.h"25#include "modronopt.h"26#include "Tgc.hpp"27#include "mmhook_internal.h"28#include "HeapIteratorAPI.h"2930#include "GCExtensions.hpp"31#include "TgcExtensions.hpp"3233/**34* Private struct used as the user data for the iterator callbacks. The regionDesc will get set35* by the region iterator callback.36*/37typedef struct FixDeadObjectsIteratorCallbackUserData {38J9MM_IterateRegionDescriptor* regionDesc; /* Temp - used internally by iterator functions */39} FixDeadObjectsIteratorCallbackUserData;4041/**42* Iterator callbacks, these are chained to eventually get to objects and their regions.43*/44static jvmtiIterationControl fix_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData);45static jvmtiIterationControl fix_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData);46static jvmtiIterationControl fix_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData);47static jvmtiIterationControl fix_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void* userData);48static jvmtiIterationControl dump_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData);4950/**51* @todo Provide function documentation52*/53static void54dumpHeap(J9JavaVM *javaVM)55{56MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);57MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);58TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;5960/* Flush any VM level changes to prepare for a safe slot walk */61TRIGGER_J9HOOK_MM_PRIVATE_WALK_HEAP_START(MM_GCExtensions::getExtensions(javaVM)->privateHookInterface, extensions->getOmrVM());6263javaVM->memoryManagerFunctions->j9mm_iterate_all_objects(javaVM, javaVM->portLibrary, j9mm_iterator_flag_include_holes, dump_objectIteratorCallback, terseExtensions);6465TRIGGER_J9HOOK_MM_PRIVATE_WALK_HEAP_END(MM_GCExtensions::getExtensions(javaVM)->privateHookInterface, extensions->getOmrVM());66}6768static jvmtiIterationControl69dump_objectIteratorCallback(J9JavaVM *vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData)70{71TgcTerseExtensions *terseExtensions = (TgcTerseExtensions*)userData;72MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vm);7374tgcExtensions->printf("*DH(%d)* %p %s",75terseExtensions->gcCount,76objectDesc->object,77objectDesc->isObject ? "a" : "f");7879if (objectDesc->isObject) {80tgcExtensions->printf(" x%p ", objectDesc->size);81tgcPrintClass(vm, J9GC_J9OBJECT_CLAZZ_VM(objectDesc->object, vm));82tgcExtensions->printf("\n");83} else {84tgcExtensions->printf(" x%p\n", objectDesc->size);85}8687return JVMTI_ITERATION_CONTINUE;88}8990/**91* @todo Provide function documentation92*/93static void94tgcHookGlobalGcStart(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)95{96MM_GlobalGCStartEvent* event = (MM_GlobalGCStartEvent*)eventData;97MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);98MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);99TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;100101terseExtensions->gcCount += 1;102/* TODO: Sovereign also prints the size of the allocation that caused the failure */103tgcExtensions->printf("*** gc(%zu) ***\n", terseExtensions->gcCount);104dumpHeap((J9JavaVM*)event->currentThread->_vm->_language_vm);105}106107/**108* @todo Provide function documentation109*/110static void111tgcHookGlobalGcEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)112{113MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;114MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);115MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);116TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;117118tgcExtensions->printf("** gc(%zu) done **\n", terseExtensions->gcCount);119dumpHeap((J9JavaVM*)event->currentThread->_vm->_language_vm);120}121122/**123* @todo Provide function documentation124*/125static void126tgcHookLocalGcStart(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)127{128MM_LocalGCStartEvent* event = (MM_LocalGCStartEvent*)eventData;129J9VMThread* vmThread = (J9VMThread*) event->currentThread->_language_vmthread;130MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);131MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);132TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;133134terseExtensions->gcCount += 1;135/* TODO: Sovereign also prints the size of the allocation that caused the failure */136tgcExtensions->printf("*** gc(%zu) ***\n", terseExtensions->gcCount);137dumpHeap(vmThread->javaVM);138}139140/**141* @todo Provide function documentation142*/143static void144tgcHookLocalGcEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)145{146MM_LocalGCEndEvent* event = (MM_LocalGCEndEvent*)eventData;147J9VMThread* vmThread = (J9VMThread*) event->currentThread->_language_vmthread;148MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);149MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);150TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;151152tgcExtensions->printf("** gc(%zu) done **\n", terseExtensions->gcCount);153dumpHeap(vmThread->javaVM);154}155156/**157* @todo Provide function documentation158*/159static void160tgcHookGlobalGcSweepEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)161{162MM_SweepEndEvent* event = (MM_SweepEndEvent*)eventData;163J9VMThread *vmThread = static_cast<J9VMThread*>(event->currentThread->_language_vmthread);164J9JavaVM* javaVM = vmThread->javaVM;165166/* Fix up the heap so that it can safely be walked later */167FixDeadObjectsIteratorCallbackUserData iteratorData;168iteratorData.regionDesc = NULL;169javaVM->memoryManagerFunctions->j9mm_iterate_heaps(javaVM, javaVM->portLibrary, 0, fix_heapIteratorCallback, &iteratorData);170}171172/**173* @todo Provide function documentation174*/175bool176tgcTerseInitialize(J9JavaVM *javaVM)177{178MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);179bool result = true;180181J9HookInterface** omrHooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);182J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);183(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_START, tgcHookGlobalGcStart, OMR_GET_CALLSITE(), NULL);184(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, tgcHookGlobalGcEnd, OMR_GET_CALLSITE(), NULL);185(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_START, tgcHookLocalGcStart, OMR_GET_CALLSITE(), NULL);186(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_END, tgcHookLocalGcEnd, OMR_GET_CALLSITE(), NULL);187(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_END, tgcHookGlobalGcSweepEnd, OMR_GET_CALLSITE(), NULL);188189return result;190}191192static jvmtiIterationControl193fix_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData)194{195FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;196vm->memoryManagerFunctions->j9mm_iterate_spaces(vm, vm->portLibrary, heapDesc, 0, fix_spaceIteratorCallback, castUserData);197return JVMTI_ITERATION_CONTINUE;198}199200static jvmtiIterationControl201fix_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData)202{203FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;204vm->memoryManagerFunctions->j9mm_iterate_regions(vm, vm->portLibrary, spaceDesc, 0, fix_regionIteratorCallback, castUserData);205return JVMTI_ITERATION_CONTINUE;206}207208static jvmtiIterationControl209fix_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData)210{211FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;212castUserData->regionDesc = regionDesc;213vm->memoryManagerFunctions->j9mm_iterate_region_objects(vm, vm->portLibrary, regionDesc, 0, fix_objectIteratorCallback, castUserData);214return JVMTI_ITERATION_CONTINUE;215}216217static jvmtiIterationControl218fix_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void* userData)219{220FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;221222/* Check the mark state of each object. If it isn't marked, build a dead object. */223if( !vm->memoryManagerFunctions->j9gc_ext_is_marked(vm, objectDesc->object) ) {224vm->memoryManagerFunctions->j9mm_abandon_object(vm, castUserData->regionDesc, objectDesc);225}226227return JVMTI_ITERATION_CONTINUE;228}229230231