Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/ConcurrentSafepointCallbackJava.cpp
5990 views
1
/*******************************************************************************
2
* Copyright (c) 2015, 2017 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
#include "ConcurrentSafepointCallbackJava.hpp"
24
#include "ModronAssertions.h"
25
26
MM_ConcurrentSafepointCallbackJava *
27
MM_ConcurrentSafepointCallbackJava::newInstance(MM_EnvironmentBase *env)
28
{
29
MM_ConcurrentSafepointCallbackJava *callback;
30
31
callback = (MM_ConcurrentSafepointCallbackJava *)env->getForge()->allocate(sizeof(MM_ConcurrentSafepointCallbackJava), MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
32
if (NULL != callback) {
33
new(callback) MM_ConcurrentSafepointCallbackJava(env);
34
if (!callback->initialize(env)) {
35
callback->kill(env);
36
return NULL;
37
}
38
}
39
return callback;
40
}
41
42
void
43
MM_ConcurrentSafepointCallbackJava::kill(MM_EnvironmentBase *env)
44
{
45
if (-1 != _asyncEventKey) {
46
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
47
javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, this->_asyncEventKey);
48
javaVM->internalVMFunctions->J9UnregisterAsyncEvent(javaVM, this->_asyncEventKey);
49
}
50
51
#if defined(AIXPPC) || defined(LINUXPPC)
52
if (_cancelAfterGC) {
53
J9HookInterface** mmHooks = J9_HOOK_INTERFACE(env->getExtensions()->omrHookInterface);
54
(*mmHooks)->J9HookUnregister(mmHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, reportGlobalGCComplete, this);
55
}
56
#endif /* defined(AIXPPC) || defined(LINUXPPC) */
57
58
env->getForge()->free(this);
59
}
60
61
bool
62
MM_ConcurrentSafepointCallbackJava::initialize(MM_EnvironmentBase *env)
63
{
64
J9HookInterface** vmHooks = J9_HOOK_INTERFACE(((J9JavaVM*)env->getLanguageVM())->hookInterface);
65
66
if (NULL == env->getOmrVMThread()) {
67
/* Register on hook for VM initialized. We can't register our async callback hooks here
68
* as we have no vmThread at this time so register on VM init hook so we can do so later
69
*/
70
(*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_INITIALIZED, vmInitialized, OMR_GET_CALLSITE(), this);
71
(*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_SHUTTING_DOWN, vmTerminating, OMR_GET_CALLSITE(), this);
72
} else {
73
registerAsyncEventHandler(env, this);
74
}
75
76
return true;
77
}
78
79
/**
80
* Called when a VM initialization is complete.
81
*
82
* @param eventNum id for event
83
* @param eventData reference to J9VMInitEvent
84
* @param userData reference to MM_ConcurrentSafepointCallbackJava
85
*
86
*/
87
void
88
MM_ConcurrentSafepointCallbackJava::vmInitialized(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
89
{
90
J9VMInitEvent* event = (J9VMInitEvent *)eventData;
91
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->vmThread->omrVMThread);
92
registerAsyncEventHandler(env, (MM_ConcurrentSafepointCallbackJava*) userData);
93
}
94
95
void
96
MM_ConcurrentSafepointCallbackJava::registerAsyncEventHandler(MM_EnvironmentBase *env, MM_ConcurrentSafepointCallbackJava *callback)
97
{
98
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
99
100
/* VM initialization complete so we will now have a vmThread under which to register our Async event handler */
101
callback->_asyncEventKey = javaVM->internalVMFunctions->J9RegisterAsyncEvent(javaVM, asyncEventHandler, callback);
102
}
103
104
void
105
MM_ConcurrentSafepointCallbackJava::asyncEventHandler(J9VMThread *vmThread, intptr_t handlerKey, void *userData)
106
{
107
MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;
108
callback->_handler(vmThread->omrVMThread, callback->_userData);
109
}
110
111
/**
112
* Called when a VM is about to terminate.
113
*
114
* @param eventNum id for event
115
* @param eventData reference to JJ9VMShutdownEvent
116
* @param userData reference to MM_ConcurrentSafepointCallbackJava
117
*
118
*/
119
void
120
MM_ConcurrentSafepointCallbackJava::vmTerminating(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
121
{
122
J9VMShutdownEvent* event = (J9VMShutdownEvent *)eventData;
123
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->vmThread->omrVMThread);
124
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
125
126
MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;
127
javaVM->internalVMFunctions->J9UnregisterAsyncEvent(javaVM, callback->_asyncEventKey);
128
}
129
130
/**
131
* Called when a global collect has completed
132
*
133
* @param eventNum id for event
134
* @param eventData reference to MM_GlobalGCEndEvent
135
* @param userData reference to MM_ConcurrentSafepointCallbackJava
136
*/
137
void
138
MM_ConcurrentSafepointCallbackJava::reportGlobalGCComplete(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
139
{
140
MM_GlobalGCEndEvent *event = (MM_GlobalGCEndEvent *)eventData;
141
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->currentThread);
142
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
143
144
MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;
145
javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, callback->_asyncEventKey);
146
}
147
148
void
149
#if defined(AIXPPC) || defined(LINUXPPC)
150
MM_ConcurrentSafepointCallbackJava::registerCallback(MM_EnvironmentBase *env, SafepointCallbackHandler handler, void *userData, bool cancelAfterGC)
151
#else
152
MM_ConcurrentSafepointCallbackJava::registerCallback(MM_EnvironmentBase *env, SafepointCallbackHandler handler, void *userData)
153
#endif /* defined(AIXPPC) || defined(LINUXPPC) */
154
{
155
Assert_MM_true(NULL == _handler);
156
Assert_MM_true(NULL == _userData);
157
158
_handler = handler;
159
_userData = userData;
160
161
#if defined(AIXPPC) || defined(LINUXPPC)
162
_cancelAfterGC = cancelAfterGC;
163
if (_cancelAfterGC) {
164
/* Register hook for global GC end. */
165
J9HookInterface** mmHooks = J9_HOOK_INTERFACE(env->getExtensions()->omrHookInterface);
166
(*mmHooks)->J9HookRegisterWithCallSite(mmHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, reportGlobalGCComplete, OMR_GET_CALLSITE(), this);
167
}
168
#endif /* defined(AIXPPC) || defined(LINUXPPC) */
169
}
170
171
void
172
MM_ConcurrentSafepointCallbackJava::requestCallback(MM_EnvironmentBase *env)
173
{
174
Assert_MM_false(NULL == _handler);
175
Assert_MM_false(NULL == _userData);
176
177
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
178
javaVM->internalVMFunctions->J9SignalAsyncEvent(javaVM, (J9VMThread *)env->getLanguageVMThread(), _asyncEventKey);
179
}
180
181
void
182
MM_ConcurrentSafepointCallbackJava::cancelCallback(MM_EnvironmentBase *env)
183
{
184
J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();
185
javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, _asyncEventKey);
186
}
187
188