Path: blob/master/runtime/gc_glue_java/ContractslotScanner.hpp
5985 views
1/*******************************************************************************2* Copyright (c) 1991, 2017 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 "Base.hpp"24#include "ClassIterator.hpp"25#include "CollectorLanguageInterfaceImpl.hpp"26#include "ConfigurationDelegate.hpp"27#include "EnvironmentBase.hpp"28#include "FinalizableObjectBuffer.hpp"29#include "FinalizableReferenceBuffer.hpp"30#include "FinalizeListManager.hpp"31#include "GCExtensions.hpp"32#include "Heap.hpp"33#include "HeapRegionDescriptorStandard.hpp"34#include "HeapRegionIteratorStandard.hpp"35#include "ModronAssertions.h"36#include "ObjectAccessBarrier.hpp"37#include "OwnableSynchronizerObjectBuffer.hpp"38#include "OwnableSynchronizerObjectList.hpp"39#include "RootScanner.hpp"40#include "RootScannerTypes.h"41#include "UnfinalizedObjectBuffer.hpp"42#include "UnfinalizedObjectList.hpp"4344/* All slot scanner for full VM slot walk.45* @copydoc MM_RootScanner46* @ingroup GC_Modron_Base47*/48class MM_ContractSlotScanner : public MM_RootScanner49{50private:51void *_srcBase;52void *_srcTop;53void *_dstBase;54protected:55public:5657private:58protected:59public:60MM_ContractSlotScanner(MM_EnvironmentBase *env, void *srcBase, void *srcTop, void *dstBase) :61MM_RootScanner(env, true)62,_srcBase(srcBase)63,_srcTop(srcTop)64,_dstBase(dstBase)65{}6667virtual void68doSlot(J9Object **slotPtr)69{70J9Object *objectPtr = *slotPtr;71if(NULL != objectPtr) {72if((objectPtr >= (J9Object *)_srcBase) && (objectPtr < (J9Object *)_srcTop)) {73objectPtr = (J9Object *)((((UDATA)objectPtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));74*slotPtr = objectPtr;75}76}77}7879virtual void80doClass(J9Class *clazz)81{82volatile j9object_t *objectSlotPtr = NULL;8384/* walk all object slots */85GC_ClassIterator classIterator(_env, clazz);86while((objectSlotPtr = classIterator.nextSlot()) != NULL) {87/* discard volatile since we must be in stop-the-world mode */88doSlot((j9object_t*)objectSlotPtr);89}90/* There is no need to walk the J9Class slots since no values within this struct could91* move during a nursery contract.92*/93}9495virtual void96scanUnfinalizedObjects(MM_EnvironmentBase *env)97{98reportScanningStarted(RootScannerEntity_UnfinalizedObjects);99100/* Only walk MEMORY_TYPE_NEW regions since MEMORY_TYPE_OLD regions would not contain101* any objects that would move during a nursery contract.102*/103MM_HeapRegionDescriptorStandard *region = NULL;104GC_HeapRegionIteratorStandard regionIterator(env->getExtensions()->heap->getHeapRegionManager());105while(NULL != (region = regionIterator.nextRegion())) {106if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {107MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);108for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {109MM_UnfinalizedObjectList *list = ®ionExtension->_unfinalizedObjectLists[i];110list->startUnfinalizedProcessing();111}112}113}114115GC_HeapRegionIteratorStandard regionIterator2(env->getExtensions()->heap->getHeapRegionManager());116while(NULL != (region = regionIterator2.nextRegion())) {117if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {118MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);119for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {120MM_UnfinalizedObjectList *list = ®ionExtension->_unfinalizedObjectLists[i];121if (!list->wasEmpty()) {122J9Object *object = list->getPriorList();123while (NULL != object) {124J9Object *movePtr = object;125if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {126movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));127}128/* read the next link out of the moved copy of the object before we add it to the buffer */129object = _extensions->accessBarrier->getFinalizeLink(movePtr);130/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */131env->getGCEnvironment()->_unfinalizedObjectBuffer->add(env, movePtr);132}133}134}135}136}137138/* restore everything to a flushed state before exiting */139env->getGCEnvironment()->_unfinalizedObjectBuffer->flush(env);140reportScanningEnded(RootScannerEntity_UnfinalizedObjects);141}142143virtual void144scanOwnableSynchronizerObjects(MM_EnvironmentBase *env)145{146reportScanningStarted(RootScannerEntity_OwnableSynchronizerObjects);147148/* Only walk MEMORY_TYPE_NEW regions since MEMORY_TYPE_OLD regions would not contain149* any objects that would move during a nursery contract.150*/151MM_HeapRegionDescriptorStandard *region = NULL;152GC_HeapRegionIteratorStandard regionIterator(env->getExtensions()->heap->getHeapRegionManager());153while(NULL != (region = regionIterator.nextRegion())) {154if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {155MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);156for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {157MM_OwnableSynchronizerObjectList *list = ®ionExtension->_ownableSynchronizerObjectLists[i];158list->startOwnableSynchronizerProcessing();159}160}161}162163GC_HeapRegionIteratorStandard regionIterator2(env->getExtensions()->heap->getHeapRegionManager());164while(NULL != (region = regionIterator2.nextRegion())) {165if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {166MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);167for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {168MM_OwnableSynchronizerObjectList *list = ®ionExtension->_ownableSynchronizerObjectLists[i];169if (!list->wasEmpty()) {170J9Object *object = list->getPriorList();171while (NULL != object) {172J9Object *movePtr = object;173if ((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {174movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));175}176/* read the next link out of the moved copy of the object before we add it to the buffer */177J9Object *next = _extensions->accessBarrier->getOwnableSynchronizerLink(movePtr);178/* the last object in the list pointing itself, after the object moved, the link still points to old object address */179if (object != next) {180object = next;181} else {182/* reach the end of the list */183object = NULL;184}185/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */186env->getGCEnvironment()->_ownableSynchronizerObjectBuffer->add(env, movePtr);187}188}189}190}191}192193/* restore everything to a flushed state before exiting */194env->getGCEnvironment()->_ownableSynchronizerObjectBuffer->flush(env);195reportScanningEnded(RootScannerEntity_OwnableSynchronizerObjects);196}197198#if defined(J9VM_GC_FINALIZATION)199void200doFinalizableObject(J9Object *objectPtr)201{202Assert_MM_unreachable();203}204205virtual void206scanFinalizableObjects(MM_EnvironmentBase *env)207{208reportScanningStarted(RootScannerEntity_FinalizableObjects);209210GC_FinalizeListManager * finalizeListManager = _extensions->finalizeListManager;211{212GC_FinalizableObjectBuffer objectBuffer(_extensions);213/* walk finalizable objects loaded by the system class loader */214j9object_t systemObject = finalizeListManager->resetSystemFinalizableObjects();215while (NULL != systemObject) {216J9Object *movePtr = systemObject;217if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {218movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));219}220/* read the next link out of the moved copy of the object before we add it to the buffer */221systemObject = _extensions->accessBarrier->getFinalizeLink(movePtr);222/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */223objectBuffer.add(env, movePtr);224}225objectBuffer.flush(env);226}227228{229GC_FinalizableObjectBuffer objectBuffer(_extensions);230/* walk finalizable objects loaded by the all other class loaders */231j9object_t defaultObject = finalizeListManager->resetDefaultFinalizableObjects();232while (NULL != defaultObject) {233J9Object *movePtr = defaultObject;234if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {235movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));236}237/* read the next link out of the moved copy of the object before we add it to the buffer */238defaultObject = _extensions->accessBarrier->getFinalizeLink(movePtr);239/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */240objectBuffer.add(env, movePtr);241}242objectBuffer.flush(env);243}244245{246/* walk reference objects */247GC_FinalizableReferenceBuffer referenceBuffer(_extensions);248j9object_t referenceObject = finalizeListManager->resetReferenceObjects();249while (NULL != referenceObject) {250J9Object *movePtr = referenceObject;251if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {252movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));253}254/* read the next link out of the moved copy of the object before we add it to the buffer */255referenceObject = _extensions->accessBarrier->getReferenceLink(movePtr);256/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */257referenceBuffer.add(env, movePtr);258}259referenceBuffer.flush(env);260}261262reportScanningEnded(RootScannerEntity_FinalizableObjects);263}264#endif /* J9VM_GC_FINALIZATION */265};266267268