Path: blob/master/runtime/gc_trace_vlhgc/TgcInterRegionReferences.cpp
5986 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 "Tgc.hpp"26#include "mmhook.h"2728#include "TgcInterRegionReferences.hpp"2930#include "ClassLoaderRememberedSet.hpp"31#include "CompactGroupManager.hpp"32#include "CycleState.hpp"33#include "EnvironmentVLHGC.hpp"34#include "GCExtensions.hpp"35#include "HeapMapIterator.hpp"36#include "HeapRegionDescriptorVLHGC.hpp"37#include "HeapRegionIteratorVLHGC.hpp"38#include "HeapRegionManager.hpp"39#include "MarkMap.hpp"40#include "MixedObjectIterator.hpp"41#include "PointerArrayIterator.hpp"42#include "TgcExtensions.hpp"434445/**46* Walk the heap to count inter-region references and then output some statistics47*/48static void49tgcHookReportInterRegionReferenceCounting(J9HookInterface** hookInterface, UDATA eventNum, void* eventData, void* userData)50{51MM_CopyForwardStartEvent* event = (MM_CopyForwardStartEvent *)eventData;52J9VMThread *vmThread = static_cast<J9VMThread*>(event->currentThread->_language_vmthread);53J9JavaVM *javaVM = vmThread->javaVM;54MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(vmThread);55MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);5657UDATA heapObjectCount = 0;58UDATA heapInSlotCount = 0;59UDATA heapOutSlotCount = 0;60UDATA heapOutObjectCount = 0;61UDATA heapBeyondSlotCount = 0;62UDATA heapBeyondObjectCount = 0;63UDATA heapCardCount = 0;6465MM_MarkMap *markMap = env->_cycleState->_markMap;66MM_HeapRegionManager *regionManager = extensions->heapRegionManager;67GC_HeapRegionIteratorVLHGC regionIterator(regionManager);68MM_HeapRegionDescriptorVLHGC *region = NULL;69PORT_ACCESS_FROM_ENVIRONMENT(env);70while (NULL != (region = regionIterator.nextRegion())) {71if (region->containsObjects()) {72UDATA objectCount = 0;73UDATA inSlotCount = 0;74UDATA outSlotCount = 0;75UDATA outObjectCount = 0;76UDATA beyondSlotCount = 0;77UDATA beyondObjectCount = 0;78UDATA cardCount = 0;7980UDATA regionCompactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);81UDATA *regionBase = (UDATA *)region->getLowAddress();82UDATA *regionTop = (UDATA *)region->getHighAddress();8384MM_HeapMapIterator iterator = MM_HeapMapIterator(extensions, markMap, regionBase, regionTop, false);85J9Object *object = NULL;86void *lastRSCLObject = NULL;87while (NULL != (object = iterator.nextObject())) {88bool cardDoesPointOut = false;89objectCount += 1;90/* first, check the validity of the object's class */91J9Class *clazz = J9GC_J9OBJECT_CLAZZ(object, env);92Assert_MM_true((UDATA)0x99669966 == clazz->eyecatcher);93/* second, verify that it is an instance of a marked class */94J9Object *classObject = (J9Object *)clazz->classObject;95Assert_MM_true(markMap->isBitSet(classObject));9697/* now that we know the class is valid, verify that this object only refers to other marked objects */98switch(extensions->objectModel.getScanType(object)) {99case GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT:100Assert_MM_true(GC_ObjectModel::REF_STATE_REMEMBERED != J9GC_J9VMJAVALANGREFERENCE_STATE(env, object));101/* fall through */102case GC_ObjectModel::SCAN_MIXED_OBJECT_LINKED:103case GC_ObjectModel::SCAN_ATOMIC_MARKABLE_REFERENCE_OBJECT:104case GC_ObjectModel::SCAN_MIXED_OBJECT:105case GC_ObjectModel::SCAN_OWNABLESYNCHRONIZER_OBJECT:106case GC_ObjectModel::SCAN_CLASS_OBJECT:107case GC_ObjectModel::SCAN_CLASSLOADER_OBJECT:108{109Assert_MM_true(extensions->classLoaderRememberedSet->isInstanceRemembered(env, object));110111GC_MixedObjectIterator mixedObjectIterator(javaVM->omrVM, object);112GC_SlotObject *slotObject = NULL;113UDATA thisObjectIn = 0;114UDATA thisObjectOut = 0;115UDATA thisObjectBeyond = 0;116bool doesPointOut = false;117bool doesPointBeyond = false;118119while (NULL != (slotObject = mixedObjectIterator.nextSlot())) {120J9Object *target = slotObject->readReferenceFromSlot();121if (NULL != target) {122MM_HeapRegionDescriptorVLHGC *dest = (MM_HeapRegionDescriptorVLHGC *)regionManager->tableDescriptorForAddress(target);123if (dest == region) {124inSlotCount += 1;125thisObjectIn += 1;126} else if (MM_CompactGroupManager::getCompactGroupNumber(env, dest) == regionCompactGroup) {127doesPointOut = true;128cardDoesPointOut = true;129outSlotCount += 1;130thisObjectOut += 1;131} else {132doesPointBeyond = true;133cardDoesPointOut = true;134beyondSlotCount += 1;135thisObjectBeyond += 1;136}137}138}139/* note that this will double-count objects which point both out _and_ beyond but that data is considered more valuable than only counting it as one type of external reference */140if (doesPointOut) {141outObjectCount += 1;142}143if (doesPointBeyond) {144beyondObjectCount += 1;145}146}147break;148case GC_ObjectModel::SCAN_POINTER_ARRAY_OBJECT:149{150Assert_MM_true(extensions->classLoaderRememberedSet->isInstanceRemembered(env, object));151152GC_PointerArrayIterator pointerArrayIterator(javaVM, object);153GC_SlotObject *slotObject = NULL;154UDATA thisObjectIn = 0;155UDATA thisObjectOut = 0;156UDATA thisObjectBeyond = 0;157bool doesPointOut = false;158bool doesPointBeyond = false;159160while (NULL != (slotObject = pointerArrayIterator.nextSlot())) {161J9Object *target = slotObject->readReferenceFromSlot();162if (NULL != target) {163MM_HeapRegionDescriptorVLHGC *dest = (MM_HeapRegionDescriptorVLHGC *)regionManager->tableDescriptorForAddress(target);164if (dest == region) {165inSlotCount += 1;166thisObjectIn += 1;167} else if (MM_CompactGroupManager::getCompactGroupNumber(env, dest) == regionCompactGroup) {168doesPointOut = true;169cardDoesPointOut = true;170outSlotCount += 1;171thisObjectOut += 1;172} else {173doesPointBeyond = true;174cardDoesPointOut = true;175beyondSlotCount += 1;176thisObjectBeyond += 1;177}178}179}180/* note that this will double-count objects which point both out _and_ beyond but that data is considered more valuable than only counting it as one type of external reference */181if (doesPointOut) {182outObjectCount += 1;183}184if (doesPointBeyond) {185beyondObjectCount += 1;186}187}188break;189case GC_ObjectModel::SCAN_PRIMITIVE_ARRAY_OBJECT:190/* nothing to do */191break;192default:193Assert_MM_unreachable();194}195if (cardDoesPointOut) {196if (NULL != lastRSCLObject) {197if (((UDATA)lastRSCLObject >> CARD_SIZE_SHIFT) != ((UDATA)object >> CARD_SIZE_SHIFT)) {198cardCount += 1;199}200}201lastRSCLObject = object;202}203}204if (NULL != lastRSCLObject) {205cardCount += 1;206}207j9tty_printf(PORTLIB, "Region based %p (group %zu) has %zu objects. %zu \"in\" slots, %zu \"out\" slots (%zu objects), %zu \"beyond\" slots (%zu objects). Creates %zu out/beyond cards\n", regionBase, regionCompactGroup, objectCount, inSlotCount, outSlotCount, outObjectCount, beyondSlotCount, beyondObjectCount, cardCount);208heapObjectCount += objectCount;209heapInSlotCount += inSlotCount;210heapOutSlotCount += outSlotCount;211heapOutObjectCount += outObjectCount;212heapBeyondSlotCount += beyondSlotCount;213heapBeyondObjectCount += beyondObjectCount;214heapCardCount += cardCount;215}216}217j9tty_printf(PORTLIB, "Total heap has %zu objects. %zu \"in\" slots, %zu \"out\" slots (%zu objects), %zu \"beyond\" slots (%zu objects). Creates %zu out/beyond cards\n", heapObjectCount, heapInSlotCount, heapOutSlotCount, heapOutObjectCount, heapBeyondSlotCount, heapBeyondObjectCount, heapCardCount);218}219220221/**222* Initialize inter region reference tgc tracing.223*/224bool225tgcInterRegionReferencesInitialize(J9JavaVM *javaVM)226{227MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);228bool result = true;229230J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);231(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_COPY_FORWARD_END, tgcHookReportInterRegionReferenceCounting, OMR_GET_CALLSITE(), javaVM);232PORT_ACCESS_FROM_JAVAVM(javaVM);233j9tty_printf(PORTLIB, "TGC inter-region references initialized.\nLegend:\n"234"\t\"in\" slot refers to a slot which points into the same region which contains its object\n"235"\t\"out\" slot refers to a slot which points into a different region from that which contains its object, yet is in the same compact group\n"236"\t\"beyond\" slot refers to a slot which points into a different region from that which contains its object which is also in a different compact group\n"237"\t\"out\" or \"beyond\" objects contain \"out\" or \"beyond\" slots, respectively (an object which contains both will be in both totals)\n"238);239240return result;241}242243void244tgcInterRegionReferencesTearDown(J9JavaVM *javaVM)245{246}247248249