Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_base/FinalizeListManager.cpp
5986 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2019 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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
22
*******************************************************************************/
23
24
#include "j9.h"
25
#include "j9cfg.h"
26
#include "j9port.h"
27
#include "ModronAssertions.h"
28
29
#if defined(J9VM_GC_FINALIZATION)
30
31
#include "FinalizeListManager.hpp"
32
#include "GCExtensions.hpp"
33
#include "Debug.hpp"
34
#include "ObjectAccessBarrier.hpp"
35
36
/**
37
* lock the finalize list manager
38
*/
39
void
40
GC_FinalizeListManager::lock() const
41
{
42
omrthread_monitor_enter(_mutex);
43
}
44
45
/**
46
* unlock the finalize list manager
47
*/
48
void
49
GC_FinalizeListManager::unlock() const
50
{
51
omrthread_monitor_exit(_mutex);
52
}
53
54
/**
55
* create and initialize with defaults new instance of FinalizeListManager
56
* @return Pointer to FinalizeListmanager if initialisation successful, NULL otherwise
57
*/
58
GC_FinalizeListManager *
59
GC_FinalizeListManager::newInstance(MM_EnvironmentBase *env)
60
{
61
GC_FinalizeListManager *manager;
62
63
manager = (GC_FinalizeListManager *)env->getForge()->allocate(sizeof(GC_FinalizeListManager), MM_AllocationCategory::FINALIZE, J9_GET_CALLSITE());
64
if (manager) {
65
new(manager) GC_FinalizeListManager(MM_GCExtensions::getExtensions(env));
66
if (!manager->initialize()) {
67
manager->kill(env);
68
return NULL;
69
}
70
}
71
72
return manager;
73
}
74
75
/**
76
* deinitialize the instance of FinalizeListManager and deallocate the memory
77
*/
78
void
79
GC_FinalizeListManager::kill(MM_EnvironmentBase *env)
80
{
81
tearDown();
82
env->getForge()->free(this);
83
}
84
85
/**
86
* initialize with default values and create the mutex
87
* @return true if initialisation successful, false otherwise.
88
*/
89
bool
90
GC_FinalizeListManager::initialize()
91
{
92
if (omrthread_monitor_init_with_name(&_mutex, 0, "FinalizeListManager")) {
93
_mutex = NULL;
94
return false;
95
}
96
97
return true;
98
}
99
100
/**
101
* deinitialize FinalizeListManager (destroy the mutex)
102
*/
103
void
104
GC_FinalizeListManager::tearDown()
105
{
106
if(NULL != _mutex) {
107
omrthread_monitor_destroy(_mutex);
108
_mutex = NULL;
109
}
110
}
111
112
void
113
GC_FinalizeListManager::addSystemFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount)
114
{
115
lock();
116
117
_extensions->accessBarrier->setFinalizeLink(tail, _systemFinalizableObjects);
118
_systemFinalizableObjects = head;
119
_systemFinalizableObjectCount += objectCount;
120
121
unlock();
122
}
123
124
j9object_t
125
GC_FinalizeListManager::popSystemFinalizableObject()
126
{
127
j9object_t value = _systemFinalizableObjects;
128
129
if (NULL != value) {
130
_systemFinalizableObjects = _extensions->accessBarrier->getFinalizeLink(value);
131
_systemFinalizableObjectCount -= 1;
132
}
133
134
return value;
135
}
136
137
void
138
GC_FinalizeListManager::addDefaultFinalizableObjects(j9object_t head, j9object_t tail, UDATA objectCount)
139
{
140
lock();
141
142
_extensions->accessBarrier->setFinalizeLink(tail, _defaultFinalizableObjects);
143
_defaultFinalizableObjects = head;
144
_defaultFinalizableObjectCount += objectCount;
145
146
unlock();
147
}
148
149
j9object_t
150
GC_FinalizeListManager::popDefaultFinalizableObject()
151
{
152
j9object_t value = _defaultFinalizableObjects;
153
154
if (NULL != value) {
155
_defaultFinalizableObjects = _extensions->accessBarrier->getFinalizeLink(value);
156
_defaultFinalizableObjectCount -= 1;
157
}
158
159
return value;
160
}
161
162
void
163
GC_FinalizeListManager::addReferenceObjects(j9object_t head, j9object_t tail, UDATA objectCount)
164
{
165
lock();
166
167
_extensions->accessBarrier->setReferenceLink(tail, _referenceObjects);
168
_referenceObjects = head;
169
_referenceObjectCount += objectCount;
170
171
unlock();
172
}
173
174
j9object_t
175
GC_FinalizeListManager::popReferenceObject()
176
{
177
j9object_t value = _referenceObjects;
178
179
if (NULL != value) {
180
_referenceObjects = _extensions->accessBarrier->getReferenceLink(value);
181
_referenceObjectCount -= 1;
182
}
183
184
return value;
185
}
186
187
void
188
GC_FinalizeListManager::addClassLoaders(J9ClassLoader *head, J9ClassLoader *tail, UDATA count)
189
{
190
lock();
191
192
tail->unloadLink = _classLoaders;
193
_classLoaders = head;
194
_classLoaderCount += count;
195
196
unlock();
197
}
198
199
J9ClassLoader *
200
GC_FinalizeListManager::popClassLoader()
201
{
202
J9ClassLoader *value = _classLoaders;
203
204
if (NULL != value) {
205
_classLoaders = value->unloadLink;
206
_classLoaderCount -= 1;
207
}
208
209
return value;
210
}
211
212
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
213
J9ClassLoader *
214
GC_FinalizeListManager::popRequiredClassLoaderForForcedClassLoaderUnload()
215
{
216
J9ClassLoader *returnValue = NULL;
217
J9ClassLoader *classLoader = _classLoaders;
218
J9ClassLoader *previousLoader = NULL;
219
while (NULL != classLoader) {
220
if (NULL != classLoader->gcThreadNotification) {
221
returnValue = classLoader;
222
if (NULL == previousLoader) {
223
_classLoaders = classLoader->unloadLink;
224
} else {
225
previousLoader->unloadLink = classLoader->unloadLink;
226
227
}
228
_classLoaderCount -= 1;
229
break;
230
}
231
previousLoader = classLoader;
232
classLoader = classLoader->unloadLink;
233
}
234
235
return returnValue;
236
}
237
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
238
239
GC_FinalizeJob *
240
GC_FinalizeListManager::consumeJob(J9VMThread *vmThread, GC_FinalizeJob * job)
241
{
242
Assert_MM_true(J9_PUBLIC_FLAGS_VM_ACCESS == (vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS));
243
Assert_MM_true(1 == omrthread_monitor_owned_by_self(_mutex)); /* caller must be holding _mutex */
244
245
{
246
j9object_t referenceObject = popReferenceObject();
247
if (NULL != referenceObject) {
248
job->type = FINALIZE_JOB_TYPE_REFERENCE;
249
job->reference = referenceObject;
250
251
return job;
252
}
253
}
254
255
{
256
J9ClassLoader *loader = popClassLoader();
257
if (NULL != loader) {
258
job->type = FINALIZE_JOB_TYPE_CLASSLOADER;
259
job->classLoader = loader;
260
261
return job;
262
}
263
}
264
265
{
266
j9object_t defaultObject = popDefaultFinalizableObject();
267
if (NULL != defaultObject) {
268
job->type = FINALIZE_JOB_TYPE_OBJECT;
269
job->object = defaultObject;
270
271
return job;
272
}
273
}
274
275
{
276
j9object_t systemObject = popSystemFinalizableObject();
277
if (NULL != systemObject) {
278
job->type = FINALIZE_JOB_TYPE_OBJECT;
279
job->object = systemObject;
280
281
return job;
282
}
283
}
284
285
return NULL;
286
}
287
288
#endif /* J9VM_GC_FINALIZATION */
289
290