Path: blob/master/runtime/gc_base/FinalizeListManager.hpp
5985 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/**24* @file25* @ingroup GC_Base26*/2728#if !defined(FINALIZELISTMANAGER_HPP_)29#define FINALIZELISTMANAGER_HPP_3031#include "j9.h"32#include "j9cfg.h"33#include "modron.h"3435#if defined(J9VM_GC_FINALIZATION)3637#include "ObjectAccessBarrier.hpp"38#include "EnvironmentBase.hpp"39#include "GCExtensions.hpp"4041class MM_GCExtensions;42class GC_CheckFinalizableList;4344typedef enum GC_FinalizeJobType {45FINALIZE_JOB_TYPE_OBJECT = 1,46FINALIZE_JOB_TYPE_REFERENCE = 2,47FINALIZE_JOB_TYPE_CLASSLOADER = 448} GC_FinalizeJobType;49typedef struct GC_FinalizeJob {50GC_FinalizeJobType type;51union {52j9object_t object;53j9object_t reference;54J9ClassLoader *classLoader;55};56} GC_FinalizeJob;5758/**59* Provides facility for the management of the finalizer queue60* @ingroup GC_Base61*/62class GC_FinalizeListManager : public MM_BaseVirtual63{64/* Data members */65private:66MM_GCExtensions *_extensions; /**< a cached pointer to the extensions structure */67omrthread_monitor_t _mutex; /**< mutex used to add / remove jobs from the finalize lists */6869j9object_t _systemFinalizableObjects; /**< head of the linked list of objects allocated by the system classloader that need to be finalized */70UDATA _systemFinalizableObjectCount; /** count of the system finalizable object */71j9object_t _defaultFinalizableObjects; /**< head of the linked list of objects allocated by non system classloaders that need to be finalized */72UDATA _defaultFinalizableObjectCount; /** count of the default finalizable object */73j9object_t _referenceObjects; /**< head of the linked list of reference objects that need to be enqueued */74UDATA _referenceObjectCount; /** count of the reference object */75J9ClassLoader *_classLoaders; /**< head of the linked list of unloaded classloaders which have open native libraries */76UDATA _classLoaderCount; /** count of the class loaders */77protected:78public:7980/* Methods */81private:82protected:83/**84* Pop the head of the System finalizable list85*86* @note Must be called while holding this class' _mutex87*88* @return the current head of the list, or NULL if the list is empty89*/90j9object_t popSystemFinalizableObject();9192/**93* Pop the head of the default finalizable list94*95* @note Must be called while holding this class' _mutex96*97* @return the current head of the list, or NULL if the list is empty98*/99j9object_t popDefaultFinalizableObject();100101/**102* Pop the head of the reference enqueue list103*104* @note Must be called while holding this class' _mutex105*106* @return the current head of the list, or NULL if the list is empty107*/108j9object_t popReferenceObject();109110/**111* Pop the head of the classloader list112*113* @note Must be called while holding this class' _mutex114*115* @return the current head of the list, or NULL if the list is empty116*/117J9ClassLoader *popClassLoader();118119public:120void lock() const;121void unlock() const;122123/**124* Gets the number of jobs on the queue.125* @return The number of jobs on the queue.126*/127virtual UDATA getJobCount() const128{129lock();130UDATA count = _classLoaderCount + _defaultFinalizableObjectCount + _systemFinalizableObjectCount + _referenceObjectCount;131unlock();132return count;133}134135virtual UDATA getSystemCount() {return _systemFinalizableObjectCount;}136virtual UDATA getDefaultCount() {return _defaultFinalizableObjectCount;}137MMINLINE UDATA getClassloaderCount() {return _classLoaderCount;}138MMINLINE UDATA getReferenceCount() {return _referenceObjectCount;}139140static GC_FinalizeListManager *newInstance(MM_EnvironmentBase *env);141virtual void kill(MM_EnvironmentBase *env);142bool initialize();143void tearDown();144145/**146* Add the list of objects to the system finalizable list147*148* @param head[in] head of the list to add149* @param tail[in] tail of the list to add150* @param count[in] number of objects in the list to add151*/152virtual void addSystemFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount);153/**154* Add the list of objects to the default finalizable list155*156* @param head[in] head of the list to add157* @param tail[in] tail of the list to add158* @param count[in] number of objects in the list to add159*/160virtual void addDefaultFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount);161/**162* Add the list of reference objects to the reference list163*164* @param head[in] head of the list to add165* @param tail[in] tail of the list to add166* @param count[in] number of objects in the list to add167*/168void addReferenceObjects(j9object_t head, j9object_t tail, UDATA objectCount);169/**170* Add the list of classloaders to the classloader list171*172* @param head[in] head of the list to add173* @param tail[in] tail of the list to add174* @param count[in] number of objects in the list to add175*/176void addClassLoaders(J9ClassLoader *head, J9ClassLoader *tail, UDATA Count);177178/**179* Return the head of the system finalize list and set the list to NULL180*181* @return the current head of the list, or NULL if the list is empty182*/183j9object_t resetSystemFinalizableObjects()184{185j9object_t value = _systemFinalizableObjects;186_systemFinalizableObjects = NULL;187_systemFinalizableObjectCount = 0;188return value;189}190/**191* Return the head of the default finalize list and set the list to NULL192*193* @return the current head of the list, or NULL if the list is empty194*/195j9object_t resetDefaultFinalizableObjects()196{197j9object_t value = _defaultFinalizableObjects;198_defaultFinalizableObjects = NULL;199_defaultFinalizableObjectCount = 0;200return value;201}202/**203* Return the head of the reference enqueue list and set the list to NULL204*205* @return the current head of the list, or NULL if the list is empty206*/207j9object_t resetReferenceObjects()208{209j9object_t value = _referenceObjects;210_referenceObjects = NULL;211_referenceObjectCount = 0;212return value;213}214/**215* Peek the head of the System finalizable list216*217* @return the current head of the list, or NULL if the list is empty218*/219virtual j9object_t peekSystemFinalizableObject()220{221return _systemFinalizableObjects;222}223/**224* Peek the next System finalizable list object225*226* @param current[in] the current object to get the next from227*228* @return the next object of the list, or NULL229*/230virtual j9object_t peekNextSystemFinalizableObject(j9object_t current)231{232MM_ObjectAccessBarrier *barrier = _extensions->accessBarrier;233return barrier->getFinalizeLink(current);234}235/**236* Peek the head of the default finalizable list237*238* @return the current head of the list, or NULL if the list is empty239*/240virtual j9object_t peekDefaultFinalizableObject()241{242return _defaultFinalizableObjects;243}244/**245* Peek the next of the default finalizable list246*247* @param current[in] the current object to get the next from248*249* @return the next object of the list, or NULL250*/251virtual j9object_t peekNextDefaultFinalizableObject(j9object_t current)252{253MM_ObjectAccessBarrier *barrier = _extensions->accessBarrier;254return barrier->getFinalizeLink(current);255}256/**257* Peek the head of the reference list258*259* @return the current head of the list, or NULL if the list is empty260*/261MMINLINE j9object_t peekReferenceObject()262{263return _referenceObjects;264}265/**266* Peek the next of the reference list267*268* @param current[in] the current object to get the next from269*270* @return the next object of the list, or NULL271*/272MMINLINE j9object_t peekNextReferenceObject(j9object_t current)273{274MM_ObjectAccessBarrier *barrier = _extensions->accessBarrier;275return barrier->getReferenceLink(current);276}277/**278* Peek the head of the classloader list279*280* @return the current head of the list, or NULL if the list is empty281*/282MMINLINE J9ClassLoader *peekClassLoader()283{284return _classLoaders;285}286/**287* Peek the next of the classloader list288*289* @param current[in] the current classloader to get the next from290*291* @return the next classloader of the list, or NULL292*/293MMINLINE J9ClassLoader *peekNextClassLoader(J9ClassLoader *current)294{295return current->unloadLink;296}297298#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)299/**300* Pop the first classloader on this off that has a non NULL gcThreadNotification301*302* @return classLoader the first class loader on the list with a non NULL gcThreadNotification or NULL303*/304J9ClassLoader *popRequiredClassLoaderForForcedClassLoaderUnload();305#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */306307/**308* Determine if any of the lists of objects managed by the receiver are non-empty.309* @return true if any of the lists are non-empty, false if they are all empty310*/311MMINLINE bool isFinalizableObjectProcessingRequired()312{313bool result = false;314if (NULL != peekSystemFinalizableObject()) {315result = true;316} else if (NULL != peekDefaultFinalizableObject()) {317result = true;318} else if (NULL != peekReferenceObject()) {319result = true;320}321return result;322}323324/**325* Pop the next job to process326*327* @note Must be called while holding this class' _mutex328*329* @return the next job or NULL330*/331virtual GC_FinalizeJob *consumeJob(J9VMThread *vmThread, GC_FinalizeJob * job);332333334/**335* Create a FinalizeListManager object336*/337GC_FinalizeListManager(MM_GCExtensions *extensions) :338_extensions(extensions)339,_mutex(NULL)340,_systemFinalizableObjects(NULL)341,_systemFinalizableObjectCount(0)342,_defaultFinalizableObjects(NULL)343,_defaultFinalizableObjectCount(0)344,_referenceObjects(NULL)345,_referenceObjectCount(0)346,_classLoaders(NULL)347,_classLoaderCount(0)348{349_typeId = __FUNCTION__;350};351352/*353* Friends354*/355friend class GC_CheckFinalizableList; /* Temporary until DDR gccheck is updated to iterate multi-tenant finalizable queues */356};357#endif /* J9VM_GC_FINALIZATION */358#endif /* FINALIZELISTMANAGER_HPP_ */359360361