Mercurial > hg > graal-compiler
annotate src/share/vm/prims/jvmtiExtensions.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f95d63e2154a |
children | d2a62e0f25eb |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "prims/jvmtiExport.hpp" | |
27 #include "prims/jvmtiExtensions.hpp" | |
0 | 28 |
29 // the list of extension functions | |
30 GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions; | |
31 | |
32 // the list of extension events | |
33 GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events; | |
34 | |
35 | |
36 // extension function | |
37 static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, jboolean* enabled, ...) { | |
38 if (enabled == NULL) { | |
39 return JVMTI_ERROR_NULL_POINTER; | |
40 } | |
41 *enabled = (jboolean)ClassUnloading; | |
42 return JVMTI_ERROR_NONE; | |
43 } | |
44 | |
45 // register extension functions and events. In this implementation we | |
46 // have a single extension function (to prove the API) that tests if class | |
47 // unloading is enabled or disabled. We also have a single extension event | |
48 // EXT_EVENT_CLASS_UNLOAD which is used to provide the JVMDI_EVENT_CLASS_UNLOAD | |
49 // event. The function and the event are registered here. | |
50 // | |
51 void JvmtiExtensions::register_extensions() { | |
52 _ext_functions = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true); | |
53 _ext_events = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionEventInfo*>(1,true); | |
54 | |
55 // register our extension function | |
56 static jvmtiParamInfo func_params[] = { | |
57 { (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, JNI_FALSE } | |
58 }; | |
59 static jvmtiExtensionFunctionInfo ext_func = { | |
60 (jvmtiExtensionFunction)IsClassUnloadingEnabled, | |
61 (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled", | |
62 (char*)"Tell if class unloading is enabled (-noclassgc)", | |
63 sizeof(func_params)/sizeof(func_params[0]), | |
64 func_params, | |
65 0, // no non-universal errors | |
66 NULL | |
67 }; | |
68 _ext_functions->append(&ext_func); | |
69 | |
70 // register our extension event | |
71 | |
72 static jvmtiParamInfo event_params[] = { | |
73 { (char*)"JNI Environment", JVMTI_KIND_IN, JVMTI_TYPE_JNIENV, JNI_FALSE }, | |
74 { (char*)"Thread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE }, | |
75 { (char*)"Class", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, JNI_FALSE } | |
76 }; | |
77 static jvmtiExtensionEventInfo ext_event = { | |
78 EXT_EVENT_CLASS_UNLOAD, | |
79 (char*)"com.sun.hotspot.events.ClassUnload", | |
80 (char*)"CLASS_UNLOAD event", | |
81 sizeof(event_params)/sizeof(event_params[0]), | |
82 event_params | |
83 }; | |
84 _ext_events->append(&ext_event); | |
85 } | |
86 | |
87 | |
88 // return the list of extension functions | |
89 | |
90 jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env, | |
91 jint* extension_count_ptr, | |
92 jvmtiExtensionFunctionInfo** extensions) | |
93 { | |
94 guarantee(_ext_functions != NULL, "registration not done"); | |
95 | |
96 ResourceTracker rt(env); | |
97 | |
98 jvmtiExtensionFunctionInfo* ext_funcs; | |
99 jvmtiError err = rt.allocate(_ext_functions->length() * | |
100 sizeof(jvmtiExtensionFunctionInfo), | |
101 (unsigned char**)&ext_funcs); | |
102 if (err != JVMTI_ERROR_NONE) { | |
103 return err; | |
104 } | |
105 | |
106 for (int i=0; i<_ext_functions->length(); i++ ) { | |
107 ext_funcs[i].func = _ext_functions->at(i)->func; | |
108 | |
109 char *id = _ext_functions->at(i)->id; | |
110 err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id)); | |
111 if (err != JVMTI_ERROR_NONE) { | |
112 return err; | |
113 } | |
114 strcpy(ext_funcs[i].id, id); | |
115 | |
116 char *desc = _ext_functions->at(i)->short_description; | |
117 err = rt.allocate(strlen(desc)+1, | |
118 (unsigned char**)&(ext_funcs[i].short_description)); | |
119 if (err != JVMTI_ERROR_NONE) { | |
120 return err; | |
121 } | |
122 strcpy(ext_funcs[i].short_description, desc); | |
123 | |
124 // params | |
125 | |
126 jint param_count = _ext_functions->at(i)->param_count; | |
127 | |
128 ext_funcs[i].param_count = param_count; | |
129 if (param_count == 0) { | |
130 ext_funcs[i].params = NULL; | |
131 } else { | |
132 err = rt.allocate(param_count*sizeof(jvmtiParamInfo), | |
133 (unsigned char**)&(ext_funcs[i].params)); | |
134 if (err != JVMTI_ERROR_NONE) { | |
135 return err; | |
136 } | |
137 jvmtiParamInfo* src_params = _ext_functions->at(i)->params; | |
138 jvmtiParamInfo* dst_params = ext_funcs[i].params; | |
139 | |
140 for (int j=0; j<param_count; j++) { | |
141 err = rt.allocate(strlen(src_params[j].name)+1, | |
142 (unsigned char**)&(dst_params[j].name)); | |
143 if (err != JVMTI_ERROR_NONE) { | |
144 return err; | |
145 } | |
146 strcpy(dst_params[j].name, src_params[j].name); | |
147 | |
148 dst_params[j].kind = src_params[j].kind; | |
149 dst_params[j].base_type = src_params[j].base_type; | |
150 dst_params[j].null_ok = src_params[j].null_ok; | |
151 } | |
152 } | |
153 | |
154 // errors | |
155 | |
156 jint error_count = _ext_functions->at(i)->error_count; | |
157 ext_funcs[i].error_count = error_count; | |
158 if (error_count == 0) { | |
159 ext_funcs[i].errors = NULL; | |
160 } else { | |
161 err = rt.allocate(error_count*sizeof(jvmtiError), | |
162 (unsigned char**)&(ext_funcs[i].errors)); | |
163 if (err != JVMTI_ERROR_NONE) { | |
164 return err; | |
165 } | |
166 memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors, | |
167 error_count*sizeof(jvmtiError)); | |
168 } | |
169 } | |
170 | |
171 *extension_count_ptr = _ext_functions->length(); | |
172 *extensions = ext_funcs; | |
173 return JVMTI_ERROR_NONE; | |
174 } | |
175 | |
176 | |
177 // return the list of extension events | |
178 | |
179 jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env, | |
180 jint* extension_count_ptr, | |
181 jvmtiExtensionEventInfo** extensions) | |
182 { | |
183 guarantee(_ext_events != NULL, "registration not done"); | |
184 | |
185 ResourceTracker rt(env); | |
186 | |
187 jvmtiExtensionEventInfo* ext_events; | |
188 jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo), | |
189 (unsigned char**)&ext_events); | |
190 if (err != JVMTI_ERROR_NONE) { | |
191 return err; | |
192 } | |
193 | |
194 for (int i=0; i<_ext_events->length(); i++ ) { | |
195 ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index; | |
196 | |
197 char *id = _ext_events->at(i)->id; | |
198 err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id)); | |
199 if (err != JVMTI_ERROR_NONE) { | |
200 return err; | |
201 } | |
202 strcpy(ext_events[i].id, id); | |
203 | |
204 char *desc = _ext_events->at(i)->short_description; | |
205 err = rt.allocate(strlen(desc)+1, | |
206 (unsigned char**)&(ext_events[i].short_description)); | |
207 if (err != JVMTI_ERROR_NONE) { | |
208 return err; | |
209 } | |
210 strcpy(ext_events[i].short_description, desc); | |
211 | |
212 // params | |
213 | |
214 jint param_count = _ext_events->at(i)->param_count; | |
215 | |
216 ext_events[i].param_count = param_count; | |
217 if (param_count == 0) { | |
218 ext_events[i].params = NULL; | |
219 } else { | |
220 err = rt.allocate(param_count*sizeof(jvmtiParamInfo), | |
221 (unsigned char**)&(ext_events[i].params)); | |
222 if (err != JVMTI_ERROR_NONE) { | |
223 return err; | |
224 } | |
225 jvmtiParamInfo* src_params = _ext_events->at(i)->params; | |
226 jvmtiParamInfo* dst_params = ext_events[i].params; | |
227 | |
228 for (int j=0; j<param_count; j++) { | |
229 err = rt.allocate(strlen(src_params[j].name)+1, | |
230 (unsigned char**)&(dst_params[j].name)); | |
231 if (err != JVMTI_ERROR_NONE) { | |
232 return err; | |
233 } | |
234 strcpy(dst_params[j].name, src_params[j].name); | |
235 | |
236 dst_params[j].kind = src_params[j].kind; | |
237 dst_params[j].base_type = src_params[j].base_type; | |
238 dst_params[j].null_ok = src_params[j].null_ok; | |
239 } | |
240 } | |
241 } | |
242 | |
243 *extension_count_ptr = _ext_events->length(); | |
244 *extensions = ext_events; | |
245 return JVMTI_ERROR_NONE; | |
246 } | |
247 | |
248 // set callback for an extension event and enable/disable it. | |
249 | |
250 jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env, | |
251 jint extension_event_index, | |
252 jvmtiExtensionEvent callback) | |
253 { | |
254 guarantee(_ext_events != NULL, "registration not done"); | |
255 | |
256 jvmtiExtensionEventInfo* event = NULL; | |
257 | |
258 // if there are extension events registered then validate that the | |
259 // extension_event_index matches one of the registered events. | |
260 if (_ext_events != NULL) { | |
261 for (int i=0; i<_ext_events->length(); i++ ) { | |
262 if (_ext_events->at(i)->extension_event_index == extension_event_index) { | |
263 event = _ext_events->at(i); | |
264 break; | |
265 } | |
266 } | |
267 } | |
268 | |
269 // invalid event index | |
270 if (event == NULL) { | |
271 return JVMTI_ERROR_ILLEGAL_ARGUMENT; | |
272 } | |
273 | |
274 JvmtiEventController::set_extension_event_callback(env, extension_event_index, | |
275 callback); | |
276 | |
277 return JVMTI_ERROR_NONE; | |
278 } |