Path: blob/master/runtime/gc_base/FinalizeListManager.cpp
5986 views
1/*******************************************************************************2* Copyright (c) 1991, 2019 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 "ModronAssertions.h"2728#if defined(J9VM_GC_FINALIZATION)2930#include "FinalizeListManager.hpp"31#include "GCExtensions.hpp"32#include "Debug.hpp"33#include "ObjectAccessBarrier.hpp"3435/**36* lock the finalize list manager37*/38void39GC_FinalizeListManager::lock() const40{41omrthread_monitor_enter(_mutex);42}4344/**45* unlock the finalize list manager46*/47void48GC_FinalizeListManager::unlock() const49{50omrthread_monitor_exit(_mutex);51}5253/**54* create and initialize with defaults new instance of FinalizeListManager55* @return Pointer to FinalizeListmanager if initialisation successful, NULL otherwise56*/57GC_FinalizeListManager *58GC_FinalizeListManager::newInstance(MM_EnvironmentBase *env)59{60GC_FinalizeListManager *manager;6162manager = (GC_FinalizeListManager *)env->getForge()->allocate(sizeof(GC_FinalizeListManager), MM_AllocationCategory::FINALIZE, J9_GET_CALLSITE());63if (manager) {64new(manager) GC_FinalizeListManager(MM_GCExtensions::getExtensions(env));65if (!manager->initialize()) {66manager->kill(env);67return NULL;68}69}7071return manager;72}7374/**75* deinitialize the instance of FinalizeListManager and deallocate the memory76*/77void78GC_FinalizeListManager::kill(MM_EnvironmentBase *env)79{80tearDown();81env->getForge()->free(this);82}8384/**85* initialize with default values and create the mutex86* @return true if initialisation successful, false otherwise.87*/88bool89GC_FinalizeListManager::initialize()90{91if (omrthread_monitor_init_with_name(&_mutex, 0, "FinalizeListManager")) {92_mutex = NULL;93return false;94}9596return true;97}9899/**100* deinitialize FinalizeListManager (destroy the mutex)101*/102void103GC_FinalizeListManager::tearDown()104{105if(NULL != _mutex) {106omrthread_monitor_destroy(_mutex);107_mutex = NULL;108}109}110111void112GC_FinalizeListManager::addSystemFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount)113{114lock();115116_extensions->accessBarrier->setFinalizeLink(tail, _systemFinalizableObjects);117_systemFinalizableObjects = head;118_systemFinalizableObjectCount += objectCount;119120unlock();121}122123j9object_t124GC_FinalizeListManager::popSystemFinalizableObject()125{126j9object_t value = _systemFinalizableObjects;127128if (NULL != value) {129_systemFinalizableObjects = _extensions->accessBarrier->getFinalizeLink(value);130_systemFinalizableObjectCount -= 1;131}132133return value;134}135136void137GC_FinalizeListManager::addDefaultFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount)138{139lock();140141_extensions->accessBarrier->setFinalizeLink(tail, _defaultFinalizableObjects);142_defaultFinalizableObjects = head;143_defaultFinalizableObjectCount += objectCount;144145unlock();146}147148j9object_t149GC_FinalizeListManager::popDefaultFinalizableObject()150{151j9object_t value = _defaultFinalizableObjects;152153if (NULL != value) {154_defaultFinalizableObjects = _extensions->accessBarrier->getFinalizeLink(value);155_defaultFinalizableObjectCount -= 1;156}157158return value;159}160161void162GC_FinalizeListManager::addReferenceObjects(j9object_t head, j9object_t tail, UDATA objectCount)163{164lock();165166_extensions->accessBarrier->setReferenceLink(tail, _referenceObjects);167_referenceObjects = head;168_referenceObjectCount += objectCount;169170unlock();171}172173j9object_t174GC_FinalizeListManager::popReferenceObject()175{176j9object_t value = _referenceObjects;177178if (NULL != value) {179_referenceObjects = _extensions->accessBarrier->getReferenceLink(value);180_referenceObjectCount -= 1;181}182183return value;184}185186void187GC_FinalizeListManager::addClassLoaders(J9ClassLoader *head, J9ClassLoader *tail, UDATA count)188{189lock();190191tail->unloadLink = _classLoaders;192_classLoaders = head;193_classLoaderCount += count;194195unlock();196}197198J9ClassLoader *199GC_FinalizeListManager::popClassLoader()200{201J9ClassLoader *value = _classLoaders;202203if (NULL != value) {204_classLoaders = value->unloadLink;205_classLoaderCount -= 1;206}207208return value;209}210211#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)212J9ClassLoader *213GC_FinalizeListManager::popRequiredClassLoaderForForcedClassLoaderUnload()214{215J9ClassLoader *returnValue = NULL;216J9ClassLoader *classLoader = _classLoaders;217J9ClassLoader *previousLoader = NULL;218while (NULL != classLoader) {219if (NULL != classLoader->gcThreadNotification) {220returnValue = classLoader;221if (NULL == previousLoader) {222_classLoaders = classLoader->unloadLink;223} else {224previousLoader->unloadLink = classLoader->unloadLink;225226}227_classLoaderCount -= 1;228break;229}230previousLoader = classLoader;231classLoader = classLoader->unloadLink;232}233234return returnValue;235}236#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */237238GC_FinalizeJob *239GC_FinalizeListManager::consumeJob(J9VMThread *vmThread, GC_FinalizeJob * job)240{241Assert_MM_true(J9_PUBLIC_FLAGS_VM_ACCESS == (vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS));242Assert_MM_true(1 == omrthread_monitor_owned_by_self(_mutex)); /* caller must be holding _mutex */243244{245j9object_t referenceObject = popReferenceObject();246if (NULL != referenceObject) {247job->type = FINALIZE_JOB_TYPE_REFERENCE;248job->reference = referenceObject;249250return job;251}252}253254{255J9ClassLoader *loader = popClassLoader();256if (NULL != loader) {257job->type = FINALIZE_JOB_TYPE_CLASSLOADER;258job->classLoader = loader;259260return job;261}262}263264{265j9object_t defaultObject = popDefaultFinalizableObject();266if (NULL != defaultObject) {267job->type = FINALIZE_JOB_TYPE_OBJECT;268job->object = defaultObject;269270return job;271}272}273274{275j9object_t systemObject = popSystemFinalizableObject();276if (NULL != systemObject) {277job->type = FINALIZE_JOB_TYPE_OBJECT;278job->object = systemObject;279280return job;281}282}283284return NULL;285}286287#endif /* J9VM_GC_FINALIZATION */288289290