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/back/classTrack.c
38765 views
1
/*
2
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* This module tracks classes that have been prepared, so as to
28
* be able to report which have been unloaded. On VM start-up
29
* and whenever new classes are loaded, all prepared classes'
30
* signatures are attached as JVMTI tag to the class object.
31
* Class unloading is tracked by registering
32
* ObjectFree callback on class objects. When this happens, we find
33
* the signature of the unloaded class(es) and report them back
34
* to the event handler to synthesize class-unload-events.
35
*/
36
37
#include "util.h"
38
#include "bag.h"
39
#include "classTrack.h"
40
41
#define NOT_TAGGED 0
42
43
/*
44
* The JVMTI tracking env to keep track of klass tags for class-unloads
45
*/
46
static jvmtiEnv* trackingEnv;
47
48
/*
49
* A bag containing all the deleted classes' signatures. Must be accessed under
50
* classTrackLock.
51
*/
52
struct bag* deletedSignatures;
53
54
/*
55
* Lock to keep integrity of deletedSignatures.
56
*/
57
static jrawMonitorID classTrackLock;
58
59
/*
60
* Invoke the callback when classes are freed, find and record the signature
61
* in deletedSignatures. Those are only used in addPreparedClass() by the
62
* same thread.
63
*/
64
static void JNICALL
65
cbTrackingObjectFree(jvmtiEnv* jvmti_env, jlong tag)
66
{
67
debugMonitorEnter(classTrackLock);
68
if (deletedSignatures == NULL) {
69
debugMonitorExit(classTrackLock);
70
return;
71
}
72
*(char**)bagAdd(deletedSignatures) = (char*)jlong_to_ptr(tag);
73
74
debugMonitorExit(classTrackLock);
75
}
76
77
/*
78
* Called after class unloads have occurred.
79
* The signatures of classes which were unloaded are returned.
80
*/
81
struct bag *
82
classTrack_processUnloads(JNIEnv *env)
83
{
84
struct bag* deleted;
85
debugMonitorEnter(classTrackLock);
86
if (deletedSignatures == NULL) {
87
// Class tracking not initialized, nobody's interested.
88
debugMonitorExit(classTrackLock);
89
return NULL;
90
}
91
deleted = deletedSignatures;
92
deletedSignatures = bagCreateBag(sizeof(char*), 10);
93
debugMonitorExit(classTrackLock);
94
return deleted;
95
}
96
97
/*
98
* Add a class to the prepared class table.
99
*/
100
void
101
classTrack_addPreparedClass(JNIEnv *env_unused, jclass klass)
102
{
103
jvmtiError error;
104
jvmtiEnv* env = trackingEnv;
105
char* signature;
106
107
if (gdata && gdata->assertOn) {
108
// Check this is not already tagged.
109
jlong tag;
110
error = JVMTI_FUNC_PTR(trackingEnv, GetTag)(env, klass, &tag);
111
if (error != JVMTI_ERROR_NONE) {
112
EXIT_ERROR(error, "Unable to GetTag with class trackingEnv");
113
}
114
JDI_ASSERT(tag == NOT_TAGGED);
115
}
116
117
error = classSignature(klass, &signature, NULL);
118
if (error != JVMTI_ERROR_NONE) {
119
EXIT_ERROR(error,"signature");
120
}
121
error = JVMTI_FUNC_PTR(trackingEnv, SetTag)(env, klass, ptr_to_jlong(signature));
122
if (error != JVMTI_ERROR_NONE) {
123
jvmtiDeallocate(signature);
124
EXIT_ERROR(error,"SetTag");
125
}
126
}
127
128
static jboolean
129
setupEvents()
130
{
131
jvmtiError error;
132
jvmtiEventCallbacks cb;
133
jvmtiCapabilities caps;
134
memset(&caps, 0, sizeof(caps));
135
caps.can_generate_object_free_events = 1;
136
error = JVMTI_FUNC_PTR(trackingEnv, AddCapabilities)(trackingEnv, &caps);
137
if (error != JVMTI_ERROR_NONE) {
138
return JNI_FALSE;
139
}
140
memset(&cb, 0, sizeof(cb));
141
cb.ObjectFree = cbTrackingObjectFree;
142
error = JVMTI_FUNC_PTR(trackingEnv, SetEventCallbacks)(trackingEnv, &cb, sizeof(cb));
143
if (error != JVMTI_ERROR_NONE) {
144
return JNI_FALSE;
145
}
146
error = JVMTI_FUNC_PTR(trackingEnv, SetEventNotificationMode)(trackingEnv, JVMTI_ENABLE, JVMTI_EVENT_OBJECT_FREE, NULL);
147
if (error != JVMTI_ERROR_NONE) {
148
return JNI_FALSE;
149
}
150
return JNI_TRUE;
151
}
152
153
/*
154
* Called once to initialize class-tracking.
155
*/
156
void
157
classTrack_initialize(JNIEnv *env)
158
{
159
jint classCount;
160
jclass *classes;
161
jvmtiError error;
162
jint i;
163
164
deletedSignatures = NULL;
165
classTrackLock = debugMonitorCreate("Deleted class tag lock");
166
trackingEnv = getSpecialJvmti();
167
if (trackingEnv == NULL) {
168
EXIT_ERROR(AGENT_ERROR_INTERNAL, "Failed to allocate tag-tracking jvmtiEnv");
169
}
170
171
172
if (!setupEvents()) {
173
EXIT_ERROR(AGENT_ERROR_INTERNAL, "Unable to setup ObjectFree tracking");
174
}
175
176
error = allLoadedClasses(&classes, &classCount);
177
if ( error == JVMTI_ERROR_NONE ) {
178
for (i = 0; i < classCount; i++) {
179
jclass klass = classes[i];
180
jint status;
181
jint wanted = JVMTI_CLASS_STATUS_PREPARED | JVMTI_CLASS_STATUS_ARRAY;
182
status = classStatus(klass);
183
if ((status & wanted) != 0) {
184
classTrack_addPreparedClass(env, klass);
185
}
186
}
187
jvmtiDeallocate(classes);
188
} else {
189
EXIT_ERROR(error,"loaded classes array");
190
}
191
}
192
193
/*
194
* Called to activate class-tracking when a listener registers for EI_GC_FINISH.
195
*/
196
void
197
classTrack_activate(JNIEnv *env)
198
{
199
debugMonitorEnter(classTrackLock);
200
deletedSignatures = bagCreateBag(sizeof(char*), 1000);
201
debugMonitorExit(classTrackLock);
202
}
203
204
static jboolean
205
cleanDeleted(void *signatureVoid, void *arg)
206
{
207
char* sig = *(char**)signatureVoid;
208
jvmtiDeallocate(sig);
209
return JNI_TRUE;
210
}
211
212
/*
213
* Called when agent detaches.
214
*/
215
void
216
classTrack_reset(void)
217
{
218
debugMonitorEnter(classTrackLock);
219
220
if (deletedSignatures != NULL) {
221
bagEnumerateOver(deletedSignatures, cleanDeleted, NULL);
222
bagDestroyBag(deletedSignatures);
223
deletedSignatures = NULL;
224
}
225
226
debugMonitorExit(classTrackLock);
227
}
228
229