Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_base/ClassLoaderManager.hpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* 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 and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
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-exception
21
*******************************************************************************/
22
23
24
/**
25
* @file
26
* @ingroup GC_Base
27
*/
28
29
#if !defined(CLASSUNLOADMANAGER_HPP_)
30
#define CLASSUNLOADMANAGER_HPP_
31
32
#include "j9.h"
33
#include "j9cfg.h"
34
35
36
#include "BaseNonVirtual.hpp"
37
#include "EnvironmentBase.hpp"
38
#include "GCExtensions.hpp"
39
40
/* forward declarations to avoid cyclic include dependencies */
41
class MM_GCExtensions;
42
class MM_GlobalCollector;
43
class MM_HeapMap;
44
class MM_ClassUnloadStats;
45
46
class MM_ClassLoaderManager : public MM_BaseNonVirtual
47
{
48
friend class GC_ClassLoaderLinkedListIterator;
49
50
public:
51
protected:
52
private:
53
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
54
omrthread_monitor_t _undeadSegmentListMonitor;
55
J9MemorySegment *_firstUndeadSegment;
56
UDATA _undeadSegmentsTotalSize;
57
UDATA _lastUnloadNumOfClassLoaders; /**< number of class loaders last seen during a dynamic class unloading pass */
58
UDATA _lastUnloadNumOfAnonymousClasses; /**< number of anonymous classes last seen during a dynamic class unloading pass */
59
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
60
MM_GlobalCollector *_globalCollector; /**< Pointer to the global collector. Used for yielding */
61
J9ClassLoader *_classLoaders; /**< Linked list of classloaders */
62
MM_GCExtensions *_extensions; /**< GC extensions structure */
63
J9JavaVM *_javaVM; /**< Pointer to the Java VM */
64
omrthread_monitor_t _classLoaderListMonitor; /**< monitor that controls modification of the classLoader linked list */
65
66
public:
67
static MM_ClassLoaderManager *newInstance(MM_EnvironmentBase *env, MM_GlobalCollector *globalCollector);
68
void kill(MM_EnvironmentBase *env);
69
70
MM_ClassLoaderManager(MM_EnvironmentBase *env, MM_GlobalCollector *globalCollector) :
71
MM_BaseNonVirtual()
72
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
73
,_undeadSegmentListMonitor(NULL)
74
,_firstUndeadSegment(NULL)
75
,_undeadSegmentsTotalSize(0)
76
,_lastUnloadNumOfClassLoaders(0)
77
,_lastUnloadNumOfAnonymousClasses(0)
78
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
79
,_globalCollector(globalCollector)
80
,_classLoaders(NULL)
81
,_extensions(MM_GCExtensions::getExtensions(env))
82
,_javaVM((J9JavaVM *)env->getOmrVM()->_language_vm)
83
,_classLoaderListMonitor(NULL)
84
{
85
_typeId = __FUNCTION__;
86
}
87
88
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
89
/**
90
* Adds the list of memory segments to the internal queue to be reclaimed later
91
* @param listRoot The root of the segments to be added (follow nextSegmentInClassLoader link to traverse)
92
*/
93
void enqueueUndeadClassSegments(J9MemorySegment *listRoot);
94
95
/**
96
* Flushes the cached list of segments by calling the VM's freeMemorySegment method
97
* @param env The environment
98
*/
99
void flushUndeadSegments(MM_EnvironmentBase *env);
100
101
/**
102
* Returns the total amount of memory (in bytes) which would be reclaimed if the buffer were to be flushed
103
*/
104
UDATA reclaimableMemory() { return _undeadSegmentsTotalSize; }
105
106
/**
107
* Returns the number of class loaders last seen during a dynamic class unloading pass
108
*/
109
UDATA getLastUnloadNumOfClassLoaders() { return _lastUnloadNumOfClassLoaders; }
110
111
/**
112
* Set the number of class loaders last seen during a dynamic class unloading pass,
113
* (i.e. the number of classloaders currently loaded)
114
*/
115
void setLastUnloadNumOfClassLoaders();
116
117
/**
118
* Returns the number of anonymous classes last seen during a dynamic class unloading pass
119
*/
120
UDATA getLastUnloadNumOfAnonymousClasses() { return _lastUnloadNumOfAnonymousClasses; }
121
122
/**
123
* Set the number of anonymous classes last seen during a dynamic class unloading pass,
124
* (i.e. the number of anonymous classes currently loaded)
125
*/
126
void setLastUnloadNumOfAnonymousClasses();
127
128
/**
129
* Perform initial cleanup for classloader unloading. The current thread has exclusive access.
130
* The J9AccClassDying bit is set and J9HOOK_VM_CLASS_UNLOAD is triggered for each class that will be unloaded.
131
* The J9_GC_CLASS_LOADER_DEAD bit is set for each class loader that will be unloaded.
132
* J9HOOK_VM_CLASSES_UNLOAD is triggered if any classes will be unloaded.
133
*
134
* @param env[in] the main GC thread
135
* @param classLoaderUnloadList[in] the linked list of loaders to unload, connected through the unloadLink field
136
* @param markMap[in] the markMap to use to test for class loader and classes liveness
137
* @param classUnloadStats[out] returns the class unloading statistics for classes about to be unloaded
138
*/
139
void cleanUpClassLoadersStart(MM_EnvironmentBase *env, J9ClassLoader* classLoaderUnloadList, MM_HeapMap *markMap, MM_ClassUnloadStats *classUnloadStats);
140
141
/**
142
* Perform final cleanup for classloader unloading. The current thread has exclusive access.
143
*
144
* Any classes in the subclass hierarchy which are identified as dying are removed.
145
*
146
* RAM segments in the J9ClassLoaders in unloadLink are changed to UNDEAD segments and added
147
* to reclaimedSegments. ROM segments in the J9ClassLoaders in the unloadLink are freed.
148
*
149
* All J9ClassLoaders in unloadLink are freed.
150
*
151
* @note Shared libraries associated with dead classloaders are NOT unloaded by this function. Such
152
* classloaders should not be on the unloadLink list.
153
*
154
* @param env[in] the current thread
155
* @param unloadLink a list of non-finalizable dead classloaders, linked by J9ClassLoader::unloadLink
156
*
157
* @return the count of classes unloaded
158
*/
159
void cleanUpClassLoadersEnd(MM_EnvironmentBase *env, J9ClassLoader* unloadLink);
160
161
/**
162
* Frees all the ROMClass segments in the list reachable from segment following nextSegmentInClassLoader and
163
* sets all RAMClass segments to UNDEADClass segments and prepends them to the reclaimedSegments list, by
164
* reference, linked via nextSegmentInClassLoader
165
*/
166
void cleanUpSegmentsAlongClassLoaderLink(J9JavaVM *javaVM, J9MemorySegment *segment, J9MemorySegment **reclaimedSegments);
167
168
/**
169
* Remove the specified class from its subclass traversal list.
170
* The class is moved into a trivial list consisting of itself.
171
* @param env[in] the current thread
172
* @param clazzPtr[in] the class to remove
173
*/
174
void removeFromSubclassHierarchy(MM_EnvironmentBase *env, J9Class *clazzPtr);
175
176
/**
177
* Perform generic clean up for a list of class loaders to unload.
178
* @param env[in] the current thread
179
* @param classLoader[in] the list of class loaders to clean up
180
* @param reclaimedSegments[out] a linked list of memory segments to be reclaimed by cleanUpClassLoadersEnd
181
* @param unloadLink[out] a linked list of class loaders to be reclaimed by cleanUpClassLoadersEnd
182
* @param finalizationRequired[out] set to true if the finalize thread must be started, unmodified otherwise
183
*/
184
void cleanUpClassLoaders(MM_EnvironmentBase *env, J9ClassLoader *classLoadersUnloadedList, J9MemorySegment** reclaimedSegments, J9ClassLoader ** unloadLink, volatile bool* finalizationRequired);
185
186
/**
187
* Attempt to enter the class unload mutex if it is uncontended.
188
* @param env[in] the current thread
189
* @return true on success, false if the JIT has the mutex locked
190
*/
191
bool tryEnterClassUnloadMutex(MM_EnvironmentBase *env);
192
193
/**
194
* Enter the class unload mutex, waiting for the JIT to release it if necessary.
195
* @param env[in] the current thread
196
* @return the time, in microseconds, the GC was forced to wait
197
*/
198
U_64 enterClassUnloadMutex(MM_EnvironmentBase *env);
199
200
/**
201
* Release the class unload mutex.
202
* @param env[in] the current thread
203
*/
204
void exitClassUnloadMutex(MM_EnvironmentBase *env);
205
206
/**
207
* Using a mark map to identify liveness, build a linked list of class loaders to unload.
208
* @param env[in] the current thread
209
* @param markMap[in] the markMap to use to test for class loader liveness
210
* @param classUnloadStats[out] returns the class unloading statistics with class loaders visited
211
* @return the head of a linked list of class loaders to be unloaded
212
*/
213
J9ClassLoader *identifyClassLoadersToUnload(MM_EnvironmentBase *env, MM_HeapMap *markMap, MM_ClassUnloadStats *classUnloadStats);
214
215
/**
216
* Clean up memory segments in anonymous classloader
217
* @param env[in] the current thread
218
* @param reclaimedSegments[out] a linked list of memory segments to be reclaimed by cleanUpClassLoadersEnd
219
*/
220
void cleanUpSegmentsInAnonymousClassLoader(MM_EnvironmentBase *env, J9MemorySegment **reclaimedSegments);
221
222
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
223
224
/**
225
* Answer true if class unloading should be attempted, or false if insufficient class loading
226
* activity has occurred
227
*/
228
bool isTimeForClassUnloading(MM_EnvironmentBase *env);
229
230
void unlinkClassLoader(J9ClassLoader *classLoader);
231
void linkClassLoader(J9ClassLoader *classLoader);
232
233
protected:
234
bool initialize(MM_EnvironmentBase *env);
235
void tearDown(MM_EnvironmentBase *env);
236
private:
237
238
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
239
/**
240
* Scan classloader for dying classes and add them to the list
241
* @param env[in] the current thread
242
* @param classLoader[in] the list of class loaders to clean up
243
* @param markMap[in] the markMap to use to test for class loader liveness
244
* @param setAll[in] bool if true if all classes must be set dying, if false unmarked classes only
245
* @param classUnloadListStart[in] root of list dying classes should be added to
246
* @param classUnloadCountOut[out] number of classes dying added to the list
247
* @return new root to list of dying classes
248
*/
249
J9Class *addDyingClassesToList(MM_EnvironmentBase *env, J9ClassLoader * classLoader, MM_HeapMap *markMap, bool setAll, J9Class *classUnloadListStart, UDATA *classUnloadCountOut);
250
251
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
252
253
};
254
255
#endif /* CLASSUNLOADMANAGER_HPP_ */
256
257