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/Agent.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
#include <stdio.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <stddef.h>
45
46
#include "jni.h"
47
#include "jvmti.h"
48
49
#include "agent_util.h"
50
51
#include "Monitor.hpp"
52
#include "Thread.hpp"
53
#include "Agent.hpp"
54
55
/* Implementation of the Agent class */
56
57
/* Given a jvmtiEnv* and jthread, find the Thread instance */
58
Thread *
59
Agent::get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
60
{
61
jvmtiError err;
62
Thread *t;
63
64
/* This should always be in the Thread Local Storage */
65
t = NULL;
66
err = jvmti->GetThreadLocalStorage(thread, (void**)&t);
67
check_jvmti_error(jvmti, err, "get thread local storage");
68
if ( t == NULL ) {
69
/* This jthread has never been seen before? */
70
stdout_message("WARNING: Never before seen jthread?\n");
71
t = new Thread(jvmti, env, thread);
72
err = jvmti->SetThreadLocalStorage(thread, (const void*)t);
73
check_jvmti_error(jvmti, err, "set thread local storage");
74
}
75
return t;
76
}
77
78
/* Given a jvmtiEnv* and jobject, find the Monitor instance or create one */
79
Monitor *
80
Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
81
{
82
jvmtiError err;
83
Monitor *m;
84
jlong tag;
85
86
m = NULL;
87
tag = (jlong)0;
88
err = jvmti->GetTag(object, &tag);
89
check_jvmti_error(jvmti, err, "get tag");
90
/*LINTED*/
91
m = (Monitor *)(void *)(ptrdiff_t)tag;
92
if ( m == NULL ) {
93
m = new Monitor(jvmti, env, object);
94
/* Save monitor on list */
95
if (monitor_count == monitor_list_size) {
96
monitor_list_size += monitor_list_grow_size;
97
monitor_list = (Monitor**)realloc((void*)monitor_list,
98
(monitor_list_size)*(int)sizeof(Monitor*));
99
}
100
monitor_list[monitor_count] = m;
101
m->set_slot(monitor_count);
102
monitor_count++;
103
/*LINTED*/
104
tag = (jlong)(ptrdiff_t)(void *)m;
105
err = jvmti->SetTag(object, tag);
106
check_jvmti_error(jvmti, err, "set tag");
107
}
108
return m;
109
}
110
111
/* VM initialization and VM death calls to Agent */
112
Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
113
{
114
jvmtiError err;
115
116
stdout_message("Agent created..\n");
117
stdout_message("VMInit...\n");
118
/* Start monitor list */
119
monitor_count = 0;
120
monitor_list_size = initial_monitor_list_size;
121
monitor_list = (Monitor**)
122
malloc(monitor_list_size*(int)sizeof(Monitor*));
123
}
124
125
Agent::~Agent()
126
{
127
stdout_message("Agent reclaimed..\n");
128
}
129
130
void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env)
131
{
132
jvmtiError err;
133
134
/* Delete all Monitors we allocated */
135
for ( int i = 0; i < (int)monitor_count; i++ ) {
136
delete monitor_list[i];
137
}
138
free(monitor_list);
139
/* Print death message */
140
stdout_message("VMDeath...\n");
141
}
142
143
/* Thread start event, setup a new thread */
144
void Agent::thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
145
{
146
jvmtiError err;
147
Thread *t;
148
149
/* Allocate a new Thread instance, put it in the Thread Local
150
* Storage for easy access later.
151
*/
152
t = new Thread(jvmti, env, thread);
153
err = jvmti->SetThreadLocalStorage(thread, (const void*)t);
154
check_jvmti_error(jvmti, err, "set thread local storage");
155
}
156
157
158
/* Thread end event, we need to reclaim the space */
159
void Agent::thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
160
{
161
jvmtiError err;
162
Thread *t;
163
164
/* Find the thread */
165
t = get_thread(jvmti, env, thread);
166
167
/* Clear out the Thread Local Storage */
168
err = jvmti->SetThreadLocalStorage(thread, (const void*)NULL);
169
check_jvmti_error(jvmti, err, "set thread local storage");
170
171
/* Reclaim the C++ object space */
172
delete t;
173
}
174
175
/* Monitor contention begins for a thread. */
176
void Agent::monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env,
177
jthread thread, jobject object)
178
{
179
get_monitor(jvmti, env, object)->contended();
180
get_thread(jvmti, env, thread)->
181
monitor_contended_enter(jvmti, env, thread, object);
182
}
183
184
/* Monitor contention ends for a thread. */
185
void Agent::monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env,
186
jthread thread, jobject object)
187
{
188
/* Do nothing for now */
189
}
190
191
/* Monitor wait begins for a thread. */
192
void Agent::monitor_wait(jvmtiEnv* jvmti, JNIEnv *env,
193
jthread thread, jobject object, jlong timeout)
194
{
195
get_monitor(jvmti, env, object)->waited();
196
get_thread(jvmti, env, thread)->
197
monitor_wait(jvmti, env, thread, object, timeout);
198
}
199
200
/* Monitor wait ends for a thread. */
201
void Agent::monitor_waited(jvmtiEnv* jvmti, JNIEnv *env,
202
jthread thread, jobject object, jboolean timed_out)
203
{
204
if ( timed_out ) {
205
get_monitor(jvmti, env, object)->timeout();
206
}
207
get_thread(jvmti, env, thread)->
208
monitor_waited(jvmti, env, thread, object, timed_out);
209
}
210
211
/* A tagged object has been freed */
212
void Agent::object_free(jvmtiEnv* jvmti, jlong tag)
213
{
214
/* We just cast the tag to a C++ pointer and delete it.
215
* we know it can only be a Monitor *.
216
*/
217
Monitor *m;
218
/*LINTED*/
219
m = (Monitor *)(ptrdiff_t)tag;
220
if (monitor_count > 1) {
221
/* Move the last element to this Monitor's slot */
222
int slot = m->get_slot();
223
Monitor *last = monitor_list[monitor_count-1];
224
monitor_list[slot] = last;
225
last->set_slot(slot);
226
}
227
monitor_count--;
228
delete m;
229
}
230
231