Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/jvmti/waiters/waiters.cpp
38829 views
1
/*
2
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
/* Example of using JVMTI events:
42
* JVMTI_EVENT_VM_INIT
43
* JVMTI_EVENT_VM_DEATH
44
* JVMTI_EVENT_THREAD_START
45
* JVMTI_EVENT_THREAD_END
46
* JVMTI_EVENT_MONITOR_CONTENDED_ENTER
47
* JVMTI_EVENT_MONITOR_WAIT
48
* JVMTI_EVENT_MONITOR_WAITED
49
* JVMTI_EVENT_OBJECT_FREE
50
*/
51
52
#include <stdio.h>
53
#include <stdlib.h>
54
#include <string.h>
55
56
#include "jni.h"
57
#include "jvmti.h"
58
59
#include "agent_util.h"
60
61
#include "Monitor.hpp"
62
#include "Thread.hpp"
63
#include "Agent.hpp"
64
65
static jrawMonitorID vm_death_lock;
66
static jboolean vm_death_active;
67
68
/* Given a jvmtiEnv*, return the C++ Agent class instance */
69
static Agent *
70
get_agent(jvmtiEnv *jvmti)
71
{
72
jvmtiError err;
73
Agent *agent;
74
75
agent = NULL;
76
err = jvmti->GetEnvironmentLocalStorage((void**)&agent);
77
check_jvmti_error(jvmti, err, "get env local storage");
78
if ( agent == NULL ) {
79
/* This should never happen, but we should check */
80
fatal_error("ERROR: GetEnvironmentLocalStorage() returned NULL");
81
}
82
return agent;
83
}
84
85
/* Enter raw monitor */
86
static void
87
menter(jvmtiEnv *jvmti, jrawMonitorID rmon)
88
{
89
jvmtiError err;
90
91
err = jvmti->RawMonitorEnter(rmon);
92
check_jvmti_error(jvmti, err, "raw monitor enter");
93
}
94
95
/* Exit raw monitor */
96
static void
97
mexit(jvmtiEnv *jvmti, jrawMonitorID rmon)
98
{
99
jvmtiError err;
100
101
err = jvmti->RawMonitorExit(rmon);
102
check_jvmti_error(jvmti, err, "raw monitor exit");
103
}
104
105
106
/* All callbacks need to be extern "C" */
107
extern "C" {
108
static void JNICALL
109
vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
110
{
111
jvmtiError err;
112
Agent *agent;
113
114
/* Create raw monitor to protect against threads running after death */
115
err = jvmti->CreateRawMonitor("Waiters vm_death lock", &vm_death_lock);
116
check_jvmti_error(jvmti, err, "create raw monitor");
117
vm_death_active = JNI_FALSE;
118
119
/* Create an Agent instance, set JVMTI Local Storage */
120
agent = new Agent(jvmti, env, thread);
121
err = jvmti->SetEnvironmentLocalStorage((const void*)agent);
122
check_jvmti_error(jvmti, err, "set env local storage");
123
124
/* Enable all other events we want */
125
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
126
JVMTI_EVENT_VM_DEATH, NULL);
127
check_jvmti_error(jvmti, err, "set event notify");
128
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
129
JVMTI_EVENT_THREAD_START, NULL);
130
check_jvmti_error(jvmti, err, "set event notify");
131
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
132
JVMTI_EVENT_THREAD_END, NULL);
133
check_jvmti_error(jvmti, err, "set event notify");
134
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
135
JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL);
136
check_jvmti_error(jvmti, err, "set event notify");
137
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
138
JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
139
check_jvmti_error(jvmti, err, "set event notify");
140
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
141
JVMTI_EVENT_MONITOR_WAIT, NULL);
142
check_jvmti_error(jvmti, err, "set event notify");
143
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
144
JVMTI_EVENT_MONITOR_WAITED, NULL);
145
check_jvmti_error(jvmti, err, "set event notify");
146
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
147
JVMTI_EVENT_OBJECT_FREE, NULL);
148
check_jvmti_error(jvmti, err, "set event notify");
149
}
150
static void JNICALL
151
vm_death(jvmtiEnv *jvmti, JNIEnv *env)
152
{
153
jvmtiError err;
154
Agent *agent;
155
156
/* Block all callbacks */
157
menter(jvmti, vm_death_lock); {
158
/* Set flag for other callbacks */
159
vm_death_active = JNI_TRUE;
160
161
/* Inform Agent instance of VM_DEATH */
162
agent = get_agent(jvmti);
163
agent->vm_death(jvmti, env);
164
165
/* Reclaim space of Agent */
166
err = jvmti->SetEnvironmentLocalStorage((const void*)NULL);
167
check_jvmti_error(jvmti, err, "set env local storage");
168
delete agent;
169
} mexit(jvmti, vm_death_lock);
170
171
}
172
static void JNICALL
173
thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
174
{
175
menter(jvmti, vm_death_lock); {
176
if ( !vm_death_active ) {
177
get_agent(jvmti)->thread_start(jvmti, env, thread);
178
}
179
} mexit(jvmti, vm_death_lock);
180
}
181
static void JNICALL
182
thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
183
{
184
menter(jvmti, vm_death_lock); {
185
if ( !vm_death_active ) {
186
get_agent(jvmti)->thread_end(jvmti, env, thread);
187
}
188
} mexit(jvmti, vm_death_lock);
189
}
190
static void JNICALL
191
monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env,
192
jthread thread, jobject object)
193
{
194
menter(jvmti, vm_death_lock); {
195
if ( !vm_death_active ) {
196
get_agent(jvmti)->monitor_contended_enter(jvmti, env,
197
thread, object);
198
}
199
} mexit(jvmti, vm_death_lock);
200
}
201
static void JNICALL
202
monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env,
203
jthread thread, jobject object)
204
{
205
menter(jvmti, vm_death_lock); {
206
if ( !vm_death_active ) {
207
get_agent(jvmti)->monitor_contended_entered(jvmti, env,
208
thread, object);
209
}
210
} mexit(jvmti, vm_death_lock);
211
}
212
static void JNICALL
213
monitor_wait(jvmtiEnv* jvmti, JNIEnv *env,
214
jthread thread, jobject object, jlong timeout)
215
{
216
menter(jvmti, vm_death_lock); {
217
if ( !vm_death_active ) {
218
get_agent(jvmti)->monitor_wait(jvmti, env, thread,
219
object, timeout);
220
}
221
} mexit(jvmti, vm_death_lock);
222
}
223
static void JNICALL
224
monitor_waited(jvmtiEnv* jvmti, JNIEnv *env,
225
jthread thread, jobject object, jboolean timed_out)
226
{
227
menter(jvmti, vm_death_lock); {
228
if ( !vm_death_active ) {
229
get_agent(jvmti)->monitor_waited(jvmti, env, thread,
230
object, timed_out);
231
}
232
} mexit(jvmti, vm_death_lock);
233
}
234
static void JNICALL
235
object_free(jvmtiEnv* jvmti, jlong tag)
236
{
237
menter(jvmti, vm_death_lock); {
238
if ( !vm_death_active ) {
239
get_agent(jvmti)->object_free(jvmti, tag);
240
}
241
} mexit(jvmti, vm_death_lock);
242
}
243
244
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
245
JNIEXPORT jint JNICALL
246
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
247
{
248
jvmtiEnv *jvmti;
249
jint rc;
250
jvmtiError err;
251
jvmtiCapabilities capabilities;
252
jvmtiEventCallbacks callbacks;
253
254
/* Get JVMTI environment */
255
rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
256
if (rc != JNI_OK) {
257
fatal_error("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
258
return -1;
259
}
260
261
/* Get/Add JVMTI capabilities */
262
(void)memset(&capabilities, 0, sizeof(capabilities));
263
capabilities.can_generate_monitor_events = 1;
264
capabilities.can_get_monitor_info = 1;
265
capabilities.can_tag_objects = 1;
266
capabilities.can_generate_object_free_events = 1;
267
err = jvmti->AddCapabilities(&capabilities);
268
check_jvmti_error(jvmti, err, "add capabilities");
269
270
/* Set all callbacks and enable VM_INIT event notification */
271
memset(&callbacks, 0, sizeof(callbacks));
272
callbacks.VMInit = &vm_init;
273
callbacks.VMDeath = &vm_death;
274
callbacks.ThreadStart = &thread_start;
275
callbacks.ThreadEnd = &thread_end;
276
callbacks.MonitorContendedEnter = &monitor_contended_enter;
277
callbacks.MonitorContendedEntered = &monitor_contended_entered;
278
callbacks.MonitorWait = &monitor_wait;
279
callbacks.MonitorWaited = &monitor_waited;
280
callbacks.ObjectFree = &object_free;
281
err = jvmti->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks));
282
check_jvmti_error(jvmti, err, "set event callbacks");
283
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
284
JVMTI_EVENT_VM_INIT, NULL);
285
check_jvmti_error(jvmti, err, "set event notify");
286
return 0;
287
}
288
289
/* Agent_OnUnload() is called last */
290
JNIEXPORT void JNICALL
291
Agent_OnUnload(JavaVM *vm)
292
{
293
}
294
295
} /* of extern "C" */
296
297