Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiManageCapabilities.cpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
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:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 # include "incls/_precompiled.incl" | |
25 # include "incls/_jvmtiManageCapabilities.cpp.incl" | |
26 | |
27 static const jint CAPA_SIZE = (JVMTI_INTERNAL_CAPABILITY_COUNT + 7) / 8; | |
28 | |
29 // capabilities which are always potentially available | |
30 jvmtiCapabilities JvmtiManageCapabilities::always_capabilities; | |
31 | |
32 // capabilities which are potentially available during OnLoad | |
33 jvmtiCapabilities JvmtiManageCapabilities::onload_capabilities; | |
34 | |
35 // capabilities which are always potentially available | |
36 // but to only one environment | |
37 jvmtiCapabilities JvmtiManageCapabilities::always_solo_capabilities; | |
38 | |
39 // capabilities which are potentially available during OnLoad | |
40 // but to only one environment | |
41 jvmtiCapabilities JvmtiManageCapabilities::onload_solo_capabilities; | |
42 | |
43 // remaining capabilities which are always potentially available | |
44 // but to only one environment | |
45 jvmtiCapabilities JvmtiManageCapabilities::always_solo_remaining_capabilities; | |
46 | |
47 // remaining capabilities which are potentially available during OnLoad | |
48 // but to only one environment | |
49 jvmtiCapabilities JvmtiManageCapabilities::onload_solo_remaining_capabilities; | |
50 | |
51 // all capabilities ever acquired | |
52 jvmtiCapabilities JvmtiManageCapabilities::acquired_capabilities; | |
53 | |
54 void JvmtiManageCapabilities::initialize() { | |
55 always_capabilities = init_always_capabilities(); | |
56 if (JvmtiEnv::get_phase() != JVMTI_PHASE_ONLOAD) { | |
57 recompute_always_capabilities(); | |
58 } | |
59 onload_capabilities = init_onload_capabilities(); | |
60 always_solo_capabilities = init_always_solo_capabilities(); | |
61 onload_solo_capabilities = init_onload_solo_capabilities(); | |
62 always_solo_remaining_capabilities = init_always_solo_capabilities(); | |
63 onload_solo_remaining_capabilities = init_onload_solo_capabilities(); | |
64 memset(&acquired_capabilities, 0, sizeof(acquired_capabilities)); | |
65 } | |
66 | |
67 // if the capability sets are initialized in the onload phase then | |
68 // it happens before class data sharing (CDS) is initialized. If it | |
69 // turns out that CDS gets disabled then we must adjust the always | |
70 // capabilities. To ensure a consistent view of the capabililties | |
71 // anything we add here should already be in the onload set. | |
72 void JvmtiManageCapabilities::recompute_always_capabilities() { | |
73 if (!UseSharedSpaces) { | |
74 jvmtiCapabilities jc = always_capabilities; | |
75 jc.can_generate_all_class_hook_events = 1; | |
76 always_capabilities = jc; | |
77 } | |
78 } | |
79 | |
80 | |
81 // corresponding init functions | |
82 jvmtiCapabilities JvmtiManageCapabilities::init_always_capabilities() { | |
83 jvmtiCapabilities jc; | |
84 | |
85 memset(&jc, 0, sizeof(jc)); | |
86 jc.can_get_bytecodes = 1; | |
87 jc.can_signal_thread = 1; | |
88 jc.can_get_source_file_name = 1; | |
89 jc.can_get_line_numbers = 1; | |
90 jc.can_get_synthetic_attribute = 1; | |
91 jc.can_get_monitor_info = 1; | |
92 jc.can_get_constant_pool = 1; | |
93 jc.can_generate_monitor_events = 1; | |
94 jc.can_generate_garbage_collection_events = 1; | |
95 jc.can_generate_compiled_method_load_events = 1; | |
96 jc.can_generate_native_method_bind_events = 1; | |
97 jc.can_generate_vm_object_alloc_events = 1; | |
98 if (os::is_thread_cpu_time_supported()) { | |
99 jc.can_get_current_thread_cpu_time = 1; | |
100 jc.can_get_thread_cpu_time = 1; | |
101 } | |
102 jc.can_redefine_classes = 1; | |
103 jc.can_redefine_any_class = 1; | |
104 jc.can_retransform_classes = 1; | |
105 jc.can_retransform_any_class = 1; | |
106 jc.can_set_native_method_prefix = 1; | |
107 jc.can_tag_objects = 1; | |
108 jc.can_generate_object_free_events = 1; | |
109 jc.can_generate_resource_exhaustion_heap_events = 1; | |
110 jc.can_generate_resource_exhaustion_threads_events = 1; | |
111 return jc; | |
112 } | |
113 | |
114 jvmtiCapabilities JvmtiManageCapabilities::init_onload_capabilities() { | |
115 jvmtiCapabilities jc; | |
116 | |
117 memset(&jc, 0, sizeof(jc)); | |
1078 | 118 #ifndef CC_INTERP |
0 | 119 jc.can_pop_frame = 1; |
120 jc.can_force_early_return = 1; | |
1078 | 121 #endif // !CC_INTERP |
0 | 122 jc.can_get_source_debug_extension = 1; |
123 jc.can_access_local_variables = 1; | |
124 jc.can_maintain_original_method_order = 1; | |
125 jc.can_generate_all_class_hook_events = 1; | |
126 jc.can_generate_single_step_events = 1; | |
127 jc.can_generate_exception_events = 1; | |
128 jc.can_generate_frame_pop_events = 1; | |
129 jc.can_generate_method_entry_events = 1; | |
130 jc.can_generate_method_exit_events = 1; | |
131 jc.can_get_owned_monitor_info = 1; | |
132 jc.can_get_owned_monitor_stack_depth_info = 1; | |
133 jc.can_get_current_contended_monitor = 1; | |
134 // jc.can_get_monitor_info = 1; | |
135 jc.can_tag_objects = 1; // TODO: this should have been removed | |
136 jc.can_generate_object_free_events = 1; // TODO: this should have been removed | |
137 return jc; | |
138 } | |
139 | |
140 | |
141 jvmtiCapabilities JvmtiManageCapabilities::init_always_solo_capabilities() { | |
142 jvmtiCapabilities jc; | |
143 | |
144 memset(&jc, 0, sizeof(jc)); | |
145 jc.can_suspend = 1; | |
146 return jc; | |
147 } | |
148 | |
149 | |
150 jvmtiCapabilities JvmtiManageCapabilities::init_onload_solo_capabilities() { | |
151 jvmtiCapabilities jc; | |
152 | |
153 memset(&jc, 0, sizeof(jc)); | |
154 jc.can_generate_field_modification_events = 1; | |
155 jc.can_generate_field_access_events = 1; | |
156 jc.can_generate_breakpoint_events = 1; | |
157 return jc; | |
158 } | |
159 | |
160 | |
161 jvmtiCapabilities *JvmtiManageCapabilities::either(const jvmtiCapabilities *a, const jvmtiCapabilities *b, | |
162 jvmtiCapabilities *result) { | |
163 char *ap = (char *)a; | |
164 char *bp = (char *)b; | |
165 char *resultp = (char *)result; | |
166 | |
167 for (int i = 0; i < CAPA_SIZE; ++i) { | |
168 *resultp++ = *ap++ | *bp++; | |
169 } | |
170 | |
171 return result; | |
172 } | |
173 | |
174 | |
175 jvmtiCapabilities *JvmtiManageCapabilities::both(const jvmtiCapabilities *a, const jvmtiCapabilities *b, | |
176 jvmtiCapabilities *result) { | |
177 char *ap = (char *)a; | |
178 char *bp = (char *)b; | |
179 char *resultp = (char *)result; | |
180 | |
181 for (int i = 0; i < CAPA_SIZE; ++i) { | |
182 *resultp++ = *ap++ & *bp++; | |
183 } | |
184 | |
185 return result; | |
186 } | |
187 | |
188 | |
189 jvmtiCapabilities *JvmtiManageCapabilities::exclude(const jvmtiCapabilities *a, const jvmtiCapabilities *b, | |
190 jvmtiCapabilities *result) { | |
191 char *ap = (char *)a; | |
192 char *bp = (char *)b; | |
193 char *resultp = (char *)result; | |
194 | |
195 for (int i = 0; i < CAPA_SIZE; ++i) { | |
196 *resultp++ = *ap++ & ~*bp++; | |
197 } | |
198 | |
199 return result; | |
200 } | |
201 | |
202 | |
203 bool JvmtiManageCapabilities::has_some(const jvmtiCapabilities *a) { | |
204 char *ap = (char *)a; | |
205 | |
206 for (int i = 0; i < CAPA_SIZE; ++i) { | |
207 if (*ap++ != 0) { | |
208 return true; | |
209 } | |
210 } | |
211 | |
212 return false; | |
213 } | |
214 | |
215 | |
216 void JvmtiManageCapabilities::copy_capabilities(const jvmtiCapabilities *from, jvmtiCapabilities *to) { | |
217 char *ap = (char *)from; | |
218 char *resultp = (char *)to; | |
219 | |
220 for (int i = 0; i < CAPA_SIZE; ++i) { | |
221 *resultp++ = *ap++; | |
222 } | |
223 } | |
224 | |
225 | |
226 void JvmtiManageCapabilities::get_potential_capabilities(const jvmtiCapabilities *current, | |
227 const jvmtiCapabilities *prohibited, | |
228 jvmtiCapabilities *result) { | |
229 // exclude prohibited capabilities, must be before adding current | |
230 exclude(&always_capabilities, prohibited, result); | |
231 | |
232 // must include current since it may possess solo capabilities and now prohibited | |
233 either(result, current, result); | |
234 | |
235 // add other remaining | |
236 either(result, &always_solo_remaining_capabilities, result); | |
237 | |
238 // if this is during OnLoad more capabilities are available | |
239 if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { | |
240 either(result, &onload_capabilities, result); | |
241 either(result, &onload_solo_remaining_capabilities, result); | |
242 } | |
243 } | |
244 | |
245 jvmtiError JvmtiManageCapabilities::add_capabilities(const jvmtiCapabilities *current, | |
246 const jvmtiCapabilities *prohibited, | |
247 const jvmtiCapabilities *desired, | |
248 jvmtiCapabilities *result) { | |
249 // check that the capabilities being added are potential capabilities | |
250 jvmtiCapabilities temp; | |
251 get_potential_capabilities(current, prohibited, &temp); | |
252 if (has_some(exclude(desired, &temp, &temp))) { | |
253 return JVMTI_ERROR_NOT_AVAILABLE; | |
254 } | |
255 | |
256 // add to the set of ever acquired capabilities | |
257 either(&acquired_capabilities, desired, &acquired_capabilities); | |
258 | |
259 // onload capabilities that got added are now permanent - so, also remove from onload | |
260 both(&onload_capabilities, desired, &temp); | |
261 either(&always_capabilities, &temp, &always_capabilities); | |
262 exclude(&onload_capabilities, &temp, &onload_capabilities); | |
263 | |
264 // same for solo capabilities (transferred capabilities in the remaining sets handled as part of standard grab - below) | |
265 both(&onload_solo_capabilities, desired, &temp); | |
266 either(&always_solo_capabilities, &temp, &always_solo_capabilities); | |
267 exclude(&onload_solo_capabilities, &temp, &onload_solo_capabilities); | |
268 | |
269 // remove solo capabilities that are now taken | |
270 exclude(&always_solo_remaining_capabilities, desired, &always_solo_remaining_capabilities); | |
271 exclude(&onload_solo_remaining_capabilities, desired, &onload_solo_remaining_capabilities); | |
272 | |
273 // return the result | |
274 either(current, desired, result); | |
275 | |
276 update(); | |
277 | |
278 return JVMTI_ERROR_NONE; | |
279 } | |
280 | |
281 | |
282 void JvmtiManageCapabilities::relinquish_capabilities(const jvmtiCapabilities *current, | |
283 const jvmtiCapabilities *unwanted, | |
284 jvmtiCapabilities *result) { | |
285 jvmtiCapabilities to_trash; | |
286 jvmtiCapabilities temp; | |
287 | |
288 // can't give up what you don't have | |
289 both(current, unwanted, &to_trash); | |
290 | |
291 // restore solo capabilities but only those that belong | |
292 either(&always_solo_remaining_capabilities, both(&always_solo_capabilities, &to_trash, &temp), | |
293 &always_solo_remaining_capabilities); | |
294 either(&onload_solo_remaining_capabilities, both(&onload_solo_capabilities, &to_trash, &temp), | |
295 &onload_solo_remaining_capabilities); | |
296 | |
297 update(); | |
298 | |
299 // return the result | |
300 exclude(current, unwanted, result); | |
301 } | |
302 | |
303 | |
304 void JvmtiManageCapabilities::update() { | |
305 jvmtiCapabilities avail; | |
306 | |
307 // all capabilities | |
308 either(&always_capabilities, &always_solo_capabilities, &avail); | |
309 | |
310 bool interp_events = | |
311 avail.can_generate_field_access_events || | |
312 avail.can_generate_field_modification_events || | |
313 avail.can_generate_single_step_events || | |
314 avail.can_generate_frame_pop_events || | |
315 avail.can_generate_method_entry_events || | |
316 avail.can_generate_method_exit_events; | |
317 bool enter_all_methods = | |
318 interp_events || | |
319 avail.can_generate_breakpoint_events; | |
320 UseFastEmptyMethods = !enter_all_methods; | |
321 UseFastAccessorMethods = !enter_all_methods; | |
322 | |
323 if (avail.can_generate_breakpoint_events) { | |
324 RewriteFrequentPairs = false; | |
325 } | |
326 | |
327 // If can_redefine_classes is enabled in the onload phase then we know that the | |
328 // dependency information recorded by the compiler is complete. | |
329 if ((avail.can_redefine_classes || avail.can_retransform_classes) && | |
330 JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { | |
331 JvmtiExport::set_all_dependencies_are_recorded(true); | |
332 } | |
333 | |
334 JvmtiExport::set_can_get_source_debug_extension(avail.can_get_source_debug_extension); | |
335 JvmtiExport::set_can_maintain_original_method_order(avail.can_maintain_original_method_order); | |
336 JvmtiExport::set_can_post_interpreter_events(interp_events); | |
337 JvmtiExport::set_can_hotswap_or_post_breakpoint( | |
338 avail.can_generate_breakpoint_events || | |
339 avail.can_redefine_classes || | |
340 avail.can_retransform_classes); | |
341 JvmtiExport::set_can_modify_any_class( | |
342 avail.can_generate_breakpoint_events || | |
343 avail.can_generate_all_class_hook_events); | |
344 JvmtiExport::set_can_walk_any_space( | |
345 avail.can_tag_objects); // disable sharing in onload phase | |
1397
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
346 // This controls whether the compilers keep extra locals live to |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
347 // improve the debugging experience so only set them if the selected |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
348 // capabilities look like a debugger. |
0 | 349 JvmtiExport::set_can_access_local_variables( |
1397
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
350 avail.can_access_local_variables || |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
351 avail.can_generate_breakpoint_events || |
b4776199210f
6943485: JVMTI always on capabilities change code generation too much
never
parents:
1213
diff
changeset
|
352 avail.can_generate_frame_pop_events); |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1078
diff
changeset
|
353 JvmtiExport::set_can_post_on_exceptions( |
0 | 354 avail.can_generate_exception_events || |
355 avail.can_generate_frame_pop_events || | |
356 avail.can_generate_method_exit_events); | |
357 JvmtiExport::set_can_post_breakpoint(avail.can_generate_breakpoint_events); | |
358 JvmtiExport::set_can_post_field_access(avail.can_generate_field_access_events); | |
359 JvmtiExport::set_can_post_field_modification(avail.can_generate_field_modification_events); | |
360 JvmtiExport::set_can_post_method_entry(avail.can_generate_method_entry_events); | |
361 JvmtiExport::set_can_post_method_exit(avail.can_generate_method_exit_events || | |
362 avail.can_generate_frame_pop_events); | |
363 JvmtiExport::set_can_pop_frame(avail.can_pop_frame); | |
364 JvmtiExport::set_can_force_early_return(avail.can_force_early_return); | |
365 JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events); | |
366 } | |
367 | |
368 #ifndef PRODUCT | |
369 | |
370 void JvmtiManageCapabilities:: print(const jvmtiCapabilities* cap) { | |
371 tty->print_cr("----- capabilities -----"); | |
372 if (cap->can_tag_objects) | |
373 tty->print_cr("can_tag_objects"); | |
374 if (cap->can_generate_field_modification_events) | |
375 tty->print_cr("can_generate_field_modification_events"); | |
376 if (cap->can_generate_field_access_events) | |
377 tty->print_cr("can_generate_field_access_events"); | |
378 if (cap->can_get_bytecodes) | |
379 tty->print_cr("can_get_bytecodes"); | |
380 if (cap->can_get_synthetic_attribute) | |
381 tty->print_cr("can_get_synthetic_attribute"); | |
382 if (cap->can_get_owned_monitor_info) | |
383 tty->print_cr("can_get_owned_monitor_info"); | |
384 if (cap->can_get_current_contended_monitor) | |
385 tty->print_cr("can_get_current_contended_monitor"); | |
386 if (cap->can_get_monitor_info) | |
387 tty->print_cr("can_get_monitor_info"); | |
388 if (cap->can_get_constant_pool) | |
389 tty->print_cr("can_get_constant_pool"); | |
390 if (cap->can_pop_frame) | |
391 tty->print_cr("can_pop_frame"); | |
392 if (cap->can_force_early_return) | |
393 tty->print_cr("can_force_early_return"); | |
394 if (cap->can_redefine_classes) | |
395 tty->print_cr("can_redefine_classes"); | |
396 if (cap->can_retransform_classes) | |
397 tty->print_cr("can_retransform_classes"); | |
398 if (cap->can_signal_thread) | |
399 tty->print_cr("can_signal_thread"); | |
400 if (cap->can_get_source_file_name) | |
401 tty->print_cr("can_get_source_file_name"); | |
402 if (cap->can_get_line_numbers) | |
403 tty->print_cr("can_get_line_numbers"); | |
404 if (cap->can_get_source_debug_extension) | |
405 tty->print_cr("can_get_source_debug_extension"); | |
406 if (cap->can_access_local_variables) | |
407 tty->print_cr("can_access_local_variables"); | |
408 if (cap->can_maintain_original_method_order) | |
409 tty->print_cr("can_maintain_original_method_order"); | |
410 if (cap->can_generate_single_step_events) | |
411 tty->print_cr("can_generate_single_step_events"); | |
412 if (cap->can_generate_exception_events) | |
413 tty->print_cr("can_generate_exception_events"); | |
414 if (cap->can_generate_frame_pop_events) | |
415 tty->print_cr("can_generate_frame_pop_events"); | |
416 if (cap->can_generate_breakpoint_events) | |
417 tty->print_cr("can_generate_breakpoint_events"); | |
418 if (cap->can_suspend) | |
419 tty->print_cr("can_suspend"); | |
420 if (cap->can_redefine_any_class ) | |
421 tty->print_cr("can_redefine_any_class"); | |
422 if (cap->can_retransform_any_class ) | |
423 tty->print_cr("can_retransform_any_class"); | |
424 if (cap->can_get_current_thread_cpu_time) | |
425 tty->print_cr("can_get_current_thread_cpu_time"); | |
426 if (cap->can_get_thread_cpu_time) | |
427 tty->print_cr("can_get_thread_cpu_time"); | |
428 if (cap->can_generate_method_entry_events) | |
429 tty->print_cr("can_generate_method_entry_events"); | |
430 if (cap->can_generate_method_exit_events) | |
431 tty->print_cr("can_generate_method_exit_events"); | |
432 if (cap->can_generate_all_class_hook_events) | |
433 tty->print_cr("can_generate_all_class_hook_events"); | |
434 if (cap->can_generate_compiled_method_load_events) | |
435 tty->print_cr("can_generate_compiled_method_load_events"); | |
436 if (cap->can_generate_monitor_events) | |
437 tty->print_cr("can_generate_monitor_events"); | |
438 if (cap->can_generate_vm_object_alloc_events) | |
439 tty->print_cr("can_generate_vm_object_alloc_events"); | |
440 if (cap->can_generate_native_method_bind_events) | |
441 tty->print_cr("can_generate_native_method_bind_events"); | |
442 if (cap->can_generate_garbage_collection_events) | |
443 tty->print_cr("can_generate_garbage_collection_events"); | |
444 if (cap->can_generate_object_free_events) | |
445 tty->print_cr("can_generate_object_free_events"); | |
446 if (cap->can_generate_resource_exhaustion_heap_events) | |
447 tty->print_cr("can_generate_resource_exhaustion_heap_events"); | |
448 if (cap->can_generate_resource_exhaustion_threads_events) | |
449 tty->print_cr("can_generate_resource_exhaustion_threads_events"); | |
450 } | |
451 | |
452 #endif |