Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiImpl.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 | fa83ab460c54 ce6848d0666d |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
611
diff
changeset
|
2 * Copyright (c) 2003, 2007, 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:
611
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
611
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:
611
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_jvmtiImpl.cpp.incl" | |
27 | |
28 GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true); | |
29 | |
30 void JvmtiPendingMonitors::transition_raw_monitors() { | |
31 assert((Threads::number_of_threads()==1), | |
32 "Java thread has not created yet or more than one java thread \ | |
33 is running. Raw monitor transition will not work"); | |
34 JavaThread *current_java_thread = JavaThread::current(); | |
35 assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm"); | |
36 { | |
37 ThreadBlockInVM __tbivm(current_java_thread); | |
38 for(int i=0; i< count(); i++) { | |
39 JvmtiRawMonitor *rmonitor = monitors()->at(i); | |
40 int r = rmonitor->raw_enter(current_java_thread); | |
41 assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked"); | |
42 } | |
43 } | |
44 // pending monitors are converted to real monitor so delete them all. | |
45 dispose(); | |
46 } | |
47 | |
48 // | |
49 // class JvmtiAgentThread | |
50 // | |
51 // JavaThread used to wrap a thread started by an agent | |
52 // using the JVMTI method RunAgentThread. | |
53 // | |
54 | |
55 JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg) | |
56 : JavaThread(start_function_wrapper) { | |
57 _env = env; | |
58 _start_fn = start_fn; | |
59 _start_arg = start_arg; | |
60 } | |
61 | |
62 void | |
63 JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) { | |
64 // It is expected that any Agent threads will be created as | |
65 // Java Threads. If this is the case, notification of the creation | |
66 // of the thread is given in JavaThread::thread_main(). | |
67 assert(thread->is_Java_thread(), "debugger thread should be a Java Thread"); | |
68 assert(thread == JavaThread::current(), "sanity check"); | |
69 | |
70 JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread; | |
71 dthread->call_start_function(); | |
72 } | |
73 | |
74 void | |
75 JvmtiAgentThread::call_start_function() { | |
76 ThreadToNativeFromVM transition(this); | |
77 _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg); | |
78 } | |
79 | |
80 | |
81 // | |
82 // class GrowableCache - private methods | |
83 // | |
84 | |
85 void GrowableCache::recache() { | |
86 int len = _elements->length(); | |
87 | |
88 FREE_C_HEAP_ARRAY(address, _cache); | |
89 _cache = NEW_C_HEAP_ARRAY(address,len+1); | |
90 | |
91 for (int i=0; i<len; i++) { | |
92 _cache[i] = _elements->at(i)->getCacheValue(); | |
93 // | |
94 // The cache entry has gone bad. Without a valid frame pointer | |
95 // value, the entry is useless so we simply delete it in product | |
96 // mode. The call to remove() will rebuild the cache again | |
97 // without the bad entry. | |
98 // | |
99 if (_cache[i] == NULL) { | |
100 assert(false, "cannot recache NULL elements"); | |
101 remove(i); | |
102 return; | |
103 } | |
104 } | |
105 _cache[len] = NULL; | |
106 | |
107 _listener_fun(_this_obj,_cache); | |
108 } | |
109 | |
110 bool GrowableCache::equals(void* v, GrowableElement *e2) { | |
111 GrowableElement *e1 = (GrowableElement *) v; | |
112 assert(e1 != NULL, "e1 != NULL"); | |
113 assert(e2 != NULL, "e2 != NULL"); | |
114 | |
115 return e1->equals(e2); | |
116 } | |
117 | |
118 // | |
119 // class GrowableCache - public methods | |
120 // | |
121 | |
122 GrowableCache::GrowableCache() { | |
123 _this_obj = NULL; | |
124 _listener_fun = NULL; | |
125 _elements = NULL; | |
126 _cache = NULL; | |
127 } | |
128 | |
129 GrowableCache::~GrowableCache() { | |
130 clear(); | |
131 delete _elements; | |
132 FREE_C_HEAP_ARRAY(address, _cache); | |
133 } | |
134 | |
135 void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) { | |
136 _this_obj = this_obj; | |
137 _listener_fun = listener_fun; | |
138 _elements = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true); | |
139 recache(); | |
140 } | |
141 | |
142 // number of elements in the collection | |
143 int GrowableCache::length() { | |
144 return _elements->length(); | |
145 } | |
146 | |
147 // get the value of the index element in the collection | |
148 GrowableElement* GrowableCache::at(int index) { | |
149 GrowableElement *e = (GrowableElement *) _elements->at(index); | |
150 assert(e != NULL, "e != NULL"); | |
151 return e; | |
152 } | |
153 | |
154 int GrowableCache::find(GrowableElement* e) { | |
155 return _elements->find(e, GrowableCache::equals); | |
156 } | |
157 | |
158 // append a copy of the element to the end of the collection | |
159 void GrowableCache::append(GrowableElement* e) { | |
160 GrowableElement *new_e = e->clone(); | |
161 _elements->append(new_e); | |
162 recache(); | |
163 } | |
164 | |
165 // insert a copy of the element using lessthan() | |
166 void GrowableCache::insert(GrowableElement* e) { | |
167 GrowableElement *new_e = e->clone(); | |
168 _elements->append(new_e); | |
169 | |
170 int n = length()-2; | |
171 for (int i=n; i>=0; i--) { | |
172 GrowableElement *e1 = _elements->at(i); | |
173 GrowableElement *e2 = _elements->at(i+1); | |
174 if (e2->lessThan(e1)) { | |
175 _elements->at_put(i+1, e1); | |
176 _elements->at_put(i, e2); | |
177 } | |
178 } | |
179 | |
180 recache(); | |
181 } | |
182 | |
183 // remove the element at index | |
184 void GrowableCache::remove (int index) { | |
185 GrowableElement *e = _elements->at(index); | |
186 assert(e != NULL, "e != NULL"); | |
187 _elements->remove(e); | |
188 delete e; | |
189 recache(); | |
190 } | |
191 | |
192 // clear out all elements, release all heap space and | |
193 // let our listener know that things have changed. | |
194 void GrowableCache::clear() { | |
195 int len = _elements->length(); | |
196 for (int i=0; i<len; i++) { | |
197 delete _elements->at(i); | |
198 } | |
199 _elements->clear(); | |
200 recache(); | |
201 } | |
202 | |
203 void GrowableCache::oops_do(OopClosure* f) { | |
204 int len = _elements->length(); | |
205 for (int i=0; i<len; i++) { | |
206 GrowableElement *e = _elements->at(i); | |
207 e->oops_do(f); | |
208 } | |
209 } | |
210 | |
211 void GrowableCache::gc_epilogue() { | |
212 int len = _elements->length(); | |
213 // recompute the new cache value after GC | |
214 for (int i=0; i<len; i++) { | |
215 _cache[i] = _elements->at(i)->getCacheValue(); | |
216 } | |
217 } | |
218 | |
219 | |
220 // | |
221 // class JvmtiRawMonitor | |
222 // | |
223 | |
224 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) { | |
225 #ifdef ASSERT | |
226 _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name); | |
227 #else | |
228 _name = NULL; | |
229 #endif | |
230 _magic = JVMTI_RM_MAGIC; | |
231 } | |
232 | |
233 JvmtiRawMonitor::~JvmtiRawMonitor() { | |
234 #ifdef ASSERT | |
235 FreeHeap(_name); | |
236 #endif | |
237 _magic = 0; | |
238 } | |
239 | |
240 | |
611
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
241 bool |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
242 JvmtiRawMonitor::is_valid() { |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
243 int value = 0; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
244 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
245 // This object might not be a JvmtiRawMonitor so we can't assume |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
246 // the _magic field is properly aligned. Get the value in a safe |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
247 // way and then check against JVMTI_RM_MAGIC. |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
248 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
249 switch (sizeof(_magic)) { |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
250 case 2: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
251 value = Bytes::get_native_u2((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
252 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
253 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
254 case 4: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
255 value = Bytes::get_native_u4((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
256 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
257 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
258 case 8: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
259 value = Bytes::get_native_u8((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
260 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
261 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
262 default: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
263 guarantee(false, "_magic field is an unexpected size"); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
264 } |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
265 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
266 return value == JVMTI_RM_MAGIC; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
267 } |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
268 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
269 |
0 | 270 // |
271 // class JvmtiBreakpoint | |
272 // | |
273 | |
274 JvmtiBreakpoint::JvmtiBreakpoint() { | |
275 _method = NULL; | |
276 _bci = 0; | |
277 #ifdef CHECK_UNHANDLED_OOPS | |
278 // This one is always allocated with new, but check it just in case. | |
279 Thread *thread = Thread::current(); | |
280 if (thread->is_in_stack((address)&_method)) { | |
281 thread->allow_unhandled_oop((oop*)&_method); | |
282 } | |
283 #endif // CHECK_UNHANDLED_OOPS | |
284 } | |
285 | |
286 JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) { | |
287 _method = m_method; | |
288 assert(_method != NULL, "_method != NULL"); | |
289 _bci = (int) location; | |
290 #ifdef CHECK_UNHANDLED_OOPS | |
291 // Could be allocated with new and wouldn't be on the unhandled oop list. | |
292 Thread *thread = Thread::current(); | |
293 if (thread->is_in_stack((address)&_method)) { | |
294 thread->allow_unhandled_oop(&_method); | |
295 } | |
296 #endif // CHECK_UNHANDLED_OOPS | |
297 | |
298 assert(_bci >= 0, "_bci >= 0"); | |
299 } | |
300 | |
301 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { | |
302 _method = bp._method; | |
303 _bci = bp._bci; | |
304 } | |
305 | |
306 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { | |
307 Unimplemented(); | |
308 return false; | |
309 } | |
310 | |
311 bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) { | |
312 return _method == bp._method | |
313 && _bci == bp._bci; | |
314 } | |
315 | |
316 bool JvmtiBreakpoint::is_valid() { | |
317 return _method != NULL && | |
318 _bci >= 0; | |
319 } | |
320 | |
321 address JvmtiBreakpoint::getBcp() { | |
322 return _method->bcp_from(_bci); | |
323 } | |
324 | |
325 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { | |
326 ((methodOopDesc*)_method->*meth_act)(_bci); | |
327 | |
328 // add/remove breakpoint to/from versions of the method that | |
329 // are EMCP. Directly or transitively obsolete methods are | |
330 // not saved in the PreviousVersionInfo. | |
331 Thread *thread = Thread::current(); | |
332 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); | |
333 symbolOop m_name = _method->name(); | |
334 symbolOop m_signature = _method->signature(); | |
335 | |
336 { | |
337 ResourceMark rm(thread); | |
338 // PreviousVersionInfo objects returned via PreviousVersionWalker | |
339 // contain a GrowableArray of handles. We have to clean up the | |
340 // GrowableArray _after_ the PreviousVersionWalker destructor | |
341 // has destroyed the handles. | |
342 { | |
343 // search previous versions if they exist | |
344 PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part()); | |
345 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | |
346 pv_info != NULL; pv_info = pvw.next_previous_version()) { | |
347 GrowableArray<methodHandle>* methods = | |
348 pv_info->prev_EMCP_method_handles(); | |
349 | |
350 if (methods == NULL) { | |
351 // We have run into a PreviousVersion generation where | |
352 // all methods were made obsolete during that generation's | |
353 // RedefineClasses() operation. At the time of that | |
354 // operation, all EMCP methods were flushed so we don't | |
355 // have to go back any further. | |
356 // | |
357 // A NULL methods array is different than an empty methods | |
358 // array. We cannot infer any optimizations about older | |
359 // generations from an empty methods array for the current | |
360 // generation. | |
361 break; | |
362 } | |
363 | |
364 for (int i = methods->length() - 1; i >= 0; i--) { | |
365 methodHandle method = methods->at(i); | |
366 if (method->name() == m_name && method->signature() == m_signature) { | |
367 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", | |
368 meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear", | |
369 method->name()->as_C_string(), | |
370 method->signature()->as_C_string())); | |
371 assert(!method->is_obsolete(), "only EMCP methods here"); | |
372 | |
373 ((methodOopDesc*)method()->*meth_act)(_bci); | |
374 break; | |
375 } | |
376 } | |
377 } | |
378 } // pvw is cleaned up | |
379 } // rm is cleaned up | |
380 } | |
381 | |
382 void JvmtiBreakpoint::set() { | |
383 each_method_version_do(&methodOopDesc::set_breakpoint); | |
384 } | |
385 | |
386 void JvmtiBreakpoint::clear() { | |
387 each_method_version_do(&methodOopDesc::clear_breakpoint); | |
388 } | |
389 | |
390 void JvmtiBreakpoint::print() { | |
391 #ifndef PRODUCT | |
392 const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); | |
393 const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string(); | |
394 | |
395 tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp()); | |
396 #endif | |
397 } | |
398 | |
399 | |
400 // | |
401 // class VM_ChangeBreakpoints | |
402 // | |
403 // Modify the Breakpoints data structure at a safepoint | |
404 // | |
405 | |
406 void VM_ChangeBreakpoints::doit() { | |
407 switch (_operation) { | |
408 case SET_BREAKPOINT: | |
409 _breakpoints->set_at_safepoint(*_bp); | |
410 break; | |
411 case CLEAR_BREAKPOINT: | |
412 _breakpoints->clear_at_safepoint(*_bp); | |
413 break; | |
414 case CLEAR_ALL_BREAKPOINT: | |
415 _breakpoints->clearall_at_safepoint(); | |
416 break; | |
417 default: | |
418 assert(false, "Unknown operation"); | |
419 } | |
420 } | |
421 | |
422 void VM_ChangeBreakpoints::oops_do(OopClosure* f) { | |
423 // This operation keeps breakpoints alive | |
424 if (_breakpoints != NULL) { | |
425 _breakpoints->oops_do(f); | |
426 } | |
427 if (_bp != NULL) { | |
428 _bp->oops_do(f); | |
429 } | |
430 } | |
431 | |
432 // | |
433 // class JvmtiBreakpoints | |
434 // | |
435 // a JVMTI internal collection of JvmtiBreakpoint | |
436 // | |
437 | |
438 JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) { | |
439 _bps.initialize(this,listener_fun); | |
440 } | |
441 | |
442 JvmtiBreakpoints:: ~JvmtiBreakpoints() {} | |
443 | |
444 void JvmtiBreakpoints::oops_do(OopClosure* f) { | |
445 _bps.oops_do(f); | |
446 } | |
447 | |
448 void JvmtiBreakpoints::gc_epilogue() { | |
449 _bps.gc_epilogue(); | |
450 } | |
451 | |
452 void JvmtiBreakpoints::print() { | |
453 #ifndef PRODUCT | |
454 ResourceMark rm; | |
455 | |
456 int n = _bps.length(); | |
457 for (int i=0; i<n; i++) { | |
458 JvmtiBreakpoint& bp = _bps.at(i); | |
459 tty->print("%d: ", i); | |
460 bp.print(); | |
461 tty->print_cr(""); | |
462 } | |
463 #endif | |
464 } | |
465 | |
466 | |
467 void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) { | |
468 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
469 | |
470 int i = _bps.find(bp); | |
471 if (i == -1) { | |
472 _bps.append(bp); | |
473 bp.set(); | |
474 } | |
475 } | |
476 | |
477 void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) { | |
478 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
479 | |
480 int i = _bps.find(bp); | |
481 if (i != -1) { | |
482 _bps.remove(i); | |
483 bp.clear(); | |
484 } | |
485 } | |
486 | |
487 void JvmtiBreakpoints::clearall_at_safepoint() { | |
488 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
489 | |
490 int len = _bps.length(); | |
491 for (int i=0; i<len; i++) { | |
492 _bps.at(i).clear(); | |
493 } | |
494 _bps.clear(); | |
495 } | |
496 | |
497 int JvmtiBreakpoints::length() { return _bps.length(); } | |
498 | |
499 int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) { | |
500 if ( _bps.find(bp) != -1) { | |
501 return JVMTI_ERROR_DUPLICATE; | |
502 } | |
503 VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp); | |
504 VMThread::execute(&set_breakpoint); | |
505 return JVMTI_ERROR_NONE; | |
506 } | |
507 | |
508 int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) { | |
509 if ( _bps.find(bp) == -1) { | |
510 return JVMTI_ERROR_NOT_FOUND; | |
511 } | |
512 | |
513 VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); | |
514 VMThread::execute(&clear_breakpoint); | |
515 return JVMTI_ERROR_NONE; | |
516 } | |
517 | |
518 void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) { | |
519 bool changed = true; | |
520 // We are going to run thru the list of bkpts | |
521 // and delete some. This deletion probably alters | |
522 // the list in some implementation defined way such | |
523 // that when we delete entry i, the next entry might | |
524 // no longer be at i+1. To be safe, each time we delete | |
525 // an entry, we'll just start again from the beginning. | |
526 // We'll stop when we make a pass thru the whole list without | |
527 // deleting anything. | |
528 while (changed) { | |
529 int len = _bps.length(); | |
530 changed = false; | |
531 for (int i = 0; i < len; i++) { | |
532 JvmtiBreakpoint& bp = _bps.at(i); | |
533 if (bp.method()->method_holder() == klass) { | |
534 bp.clear(); | |
535 _bps.remove(i); | |
536 // This changed 'i' so we have to start over. | |
537 changed = true; | |
538 break; | |
539 } | |
540 } | |
541 } | |
542 } | |
543 | |
544 void JvmtiBreakpoints::clearall() { | |
545 VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT); | |
546 VMThread::execute(&clearall_breakpoint); | |
547 } | |
548 | |
549 // | |
550 // class JvmtiCurrentBreakpoints | |
551 // | |
552 | |
553 JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL; | |
554 address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL; | |
555 | |
556 | |
557 JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() { | |
558 if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints); | |
559 _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun); | |
560 assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL"); | |
561 return (*_jvmti_breakpoints); | |
562 } | |
563 | |
564 void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) { | |
565 JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj; | |
566 assert(this_jvmti != NULL, "this_jvmti != NULL"); | |
567 | |
568 debug_only(int n = this_jvmti->length();); | |
569 assert(cache[n] == NULL, "cache must be NULL terminated"); | |
570 | |
571 set_breakpoint_list(cache); | |
572 } | |
573 | |
574 | |
575 void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) { | |
576 if (_jvmti_breakpoints != NULL) { | |
577 _jvmti_breakpoints->oops_do(f); | |
578 } | |
579 } | |
580 | |
581 void JvmtiCurrentBreakpoints::gc_epilogue() { | |
582 if (_jvmti_breakpoints != NULL) { | |
583 _jvmti_breakpoints->gc_epilogue(); | |
584 } | |
585 } | |
586 | |
587 | |
588 /////////////////////////////////////////////////////////////// | |
589 // | |
590 // class VM_GetOrSetLocal | |
591 // | |
592 | |
593 // Constructor for non-object getter | |
594 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type) | |
595 : _thread(thread) | |
596 , _calling_thread(NULL) | |
597 , _depth(depth) | |
598 , _index(index) | |
599 , _type(type) | |
600 , _set(false) | |
601 , _jvf(NULL) | |
602 , _result(JVMTI_ERROR_NONE) | |
603 { | |
604 } | |
605 | |
606 // Constructor for object or non-object setter | |
607 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value) | |
608 : _thread(thread) | |
609 , _calling_thread(NULL) | |
610 , _depth(depth) | |
611 , _index(index) | |
612 , _type(type) | |
613 , _value(value) | |
614 , _set(true) | |
615 , _jvf(NULL) | |
616 , _result(JVMTI_ERROR_NONE) | |
617 { | |
618 } | |
619 | |
620 // Constructor for object getter | |
621 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index) | |
622 : _thread(thread) | |
623 , _calling_thread(calling_thread) | |
624 , _depth(depth) | |
625 , _index(index) | |
626 , _type(T_OBJECT) | |
627 , _set(false) | |
628 , _jvf(NULL) | |
629 , _result(JVMTI_ERROR_NONE) | |
630 { | |
631 } | |
632 | |
633 | |
634 vframe *VM_GetOrSetLocal::get_vframe() { | |
635 if (!_thread->has_last_Java_frame()) { | |
636 return NULL; | |
637 } | |
638 RegisterMap reg_map(_thread); | |
639 vframe *vf = _thread->last_java_vframe(®_map); | |
640 int d = 0; | |
641 while ((vf != NULL) && (d < _depth)) { | |
642 vf = vf->java_sender(); | |
643 d++; | |
644 } | |
645 return vf; | |
646 } | |
647 | |
648 javaVFrame *VM_GetOrSetLocal::get_java_vframe() { | |
649 vframe* vf = get_vframe(); | |
650 if (vf == NULL) { | |
651 _result = JVMTI_ERROR_NO_MORE_FRAMES; | |
652 return NULL; | |
653 } | |
654 javaVFrame *jvf = (javaVFrame*)vf; | |
655 | |
656 if (!vf->is_java_frame() || jvf->method()->is_native()) { | |
657 _result = JVMTI_ERROR_OPAQUE_FRAME; | |
658 return NULL; | |
659 } | |
660 return jvf; | |
661 } | |
662 | |
663 // Check that the klass is assignable to a type with the given signature. | |
664 // Another solution could be to use the function Klass::is_subtype_of(type). | |
665 // But the type class can be forced to load/initialize eagerly in such a case. | |
666 // This may cause unexpected consequences like CFLH or class-init JVMTI events. | |
667 // It is better to avoid such a behavior. | |
668 bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { | |
669 assert(ty_sign != NULL, "type signature must not be NULL"); | |
670 assert(thread != NULL, "thread must not be NULL"); | |
671 assert(klass != NULL, "klass must not be NULL"); | |
672 | |
673 int len = (int) strlen(ty_sign); | |
674 if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name | |
675 ty_sign++; | |
676 len -= 2; | |
677 } | |
678 symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread); | |
679 if (klass->name() == ty_sym()) { | |
680 return true; | |
681 } | |
682 // Compare primary supers | |
683 int super_depth = klass->super_depth(); | |
684 int idx; | |
685 for (idx = 0; idx < super_depth; idx++) { | |
686 if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) { | |
687 return true; | |
688 } | |
689 } | |
690 // Compare secondary supers | |
691 objArrayOop sec_supers = klass->secondary_supers(); | |
692 for (idx = 0; idx < sec_supers->length(); idx++) { | |
693 if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) { | |
694 return true; | |
695 } | |
696 } | |
697 return false; | |
698 } | |
699 | |
700 // Checks error conditions: | |
701 // JVMTI_ERROR_INVALID_SLOT | |
702 // JVMTI_ERROR_TYPE_MISMATCH | |
703 // Returns: 'true' - everything is Ok, 'false' - error code | |
704 | |
705 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { | |
706 methodOop method_oop = jvf->method(); | |
707 if (!method_oop->has_localvariable_table()) { | |
708 // Just to check index boundaries | |
709 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; | |
710 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { | |
711 _result = JVMTI_ERROR_INVALID_SLOT; | |
712 return false; | |
713 } | |
714 return true; | |
715 } | |
716 | |
717 jint num_entries = method_oop->localvariable_table_length(); | |
718 if (num_entries == 0) { | |
719 _result = JVMTI_ERROR_INVALID_SLOT; | |
720 return false; // There are no slots | |
721 } | |
722 int signature_idx = -1; | |
723 int vf_bci = jvf->bci(); | |
724 LocalVariableTableElement* table = method_oop->localvariable_table_start(); | |
725 for (int i = 0; i < num_entries; i++) { | |
726 int start_bci = table[i].start_bci; | |
727 int end_bci = start_bci + table[i].length; | |
728 | |
729 // Here we assume that locations of LVT entries | |
730 // with the same slot number cannot be overlapped | |
731 if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) { | |
732 signature_idx = (int) table[i].descriptor_cp_index; | |
733 break; | |
734 } | |
735 } | |
736 if (signature_idx == -1) { | |
737 _result = JVMTI_ERROR_INVALID_SLOT; | |
738 return false; // Incorrect slot index | |
739 } | |
740 symbolOop sign_sym = method_oop->constants()->symbol_at(signature_idx); | |
741 const char* signature = (const char *) sign_sym->as_utf8(); | |
742 BasicType slot_type = char2type(signature[0]); | |
743 | |
744 switch (slot_type) { | |
745 case T_BYTE: | |
746 case T_SHORT: | |
747 case T_CHAR: | |
748 case T_BOOLEAN: | |
749 slot_type = T_INT; | |
750 break; | |
751 case T_ARRAY: | |
752 slot_type = T_OBJECT; | |
753 break; | |
754 }; | |
755 if (_type != slot_type) { | |
756 _result = JVMTI_ERROR_TYPE_MISMATCH; | |
757 return false; | |
758 } | |
759 | |
760 jobject jobj = _value.l; | |
761 if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed | |
762 // Check that the jobject class matches the return type signature. | |
763 JavaThread* cur_thread = JavaThread::current(); | |
764 HandleMark hm(cur_thread); | |
765 | |
766 Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj)); | |
767 NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); | |
768 KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass()); | |
769 NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); | |
770 | |
771 if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) { | |
772 _result = JVMTI_ERROR_TYPE_MISMATCH; | |
773 return false; | |
774 } | |
775 } | |
776 return true; | |
777 } | |
778 | |
779 static bool can_be_deoptimized(vframe* vf) { | |
780 return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); | |
781 } | |
782 | |
783 bool VM_GetOrSetLocal::doit_prologue() { | |
784 _jvf = get_java_vframe(); | |
785 NULL_CHECK(_jvf, false); | |
786 | |
787 if (!check_slot_type(_jvf)) { | |
788 return false; | |
789 } | |
790 return true; | |
791 } | |
792 | |
793 void VM_GetOrSetLocal::doit() { | |
794 if (_set) { | |
795 // Force deoptimization of frame if compiled because it's | |
796 // possible the compiler emitted some locals as constant values, | |
797 // meaning they are not mutable. | |
798 if (can_be_deoptimized(_jvf)) { | |
799 | |
800 // Schedule deoptimization so that eventually the local | |
801 // update will be written to an interpreter frame. | |
802 VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id()); | |
803 VMThread::execute(&deopt); | |
804 | |
805 // Now store a new value for the local which will be applied | |
806 // once deoptimization occurs. Note however that while this | |
807 // write is deferred until deoptimization actually happens | |
808 // can vframe created after this point will have its locals | |
809 // reflecting this update so as far as anyone can see the | |
810 // write has already taken place. | |
811 | |
812 // If we are updating an oop then get the oop from the handle | |
813 // since the handle will be long gone by the time the deopt | |
814 // happens. The oop stored in the deferred local will be | |
815 // gc'd on its own. | |
816 if (_type == T_OBJECT) { | |
817 _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l)); | |
818 } | |
819 // Re-read the vframe so we can see that it is deoptimized | |
820 // [ Only need because of assert in update_local() ] | |
821 _jvf = get_java_vframe(); | |
822 ((compiledVFrame*)_jvf)->update_local(_type, _index, _value); | |
823 return; | |
824 } | |
825 StackValueCollection *locals = _jvf->locals(); | |
826 HandleMark hm; | |
827 | |
828 switch (_type) { | |
829 case T_INT: locals->set_int_at (_index, _value.i); break; | |
830 case T_LONG: locals->set_long_at (_index, _value.j); break; | |
831 case T_FLOAT: locals->set_float_at (_index, _value.f); break; | |
832 case T_DOUBLE: locals->set_double_at(_index, _value.d); break; | |
833 case T_OBJECT: { | |
834 Handle ob_h(JNIHandles::resolve_external_guard(_value.l)); | |
835 locals->set_obj_at (_index, ob_h); | |
836 break; | |
837 } | |
838 default: ShouldNotReachHere(); | |
839 } | |
840 _jvf->set_locals(locals); | |
841 } else { | |
842 StackValueCollection *locals = _jvf->locals(); | |
843 | |
844 if (locals->at(_index)->type() == T_CONFLICT) { | |
845 memset(&_value, 0, sizeof(_value)); | |
846 _value.l = NULL; | |
847 return; | |
848 } | |
849 | |
850 switch (_type) { | |
851 case T_INT: _value.i = locals->int_at (_index); break; | |
852 case T_LONG: _value.j = locals->long_at (_index); break; | |
853 case T_FLOAT: _value.f = locals->float_at (_index); break; | |
854 case T_DOUBLE: _value.d = locals->double_at(_index); break; | |
855 case T_OBJECT: { | |
856 // Wrap the oop to be returned in a local JNI handle since | |
857 // oops_do() no longer applies after doit() is finished. | |
858 oop obj = locals->obj_at(_index)(); | |
859 _value.l = JNIHandles::make_local(_calling_thread, obj); | |
860 break; | |
861 } | |
862 default: ShouldNotReachHere(); | |
863 } | |
864 } | |
865 } | |
866 | |
867 | |
868 bool VM_GetOrSetLocal::allow_nested_vm_operations() const { | |
869 return true; // May need to deoptimize | |
870 } | |
871 | |
872 | |
873 ///////////////////////////////////////////////////////////////////////////////////////// | |
874 | |
875 // | |
876 // class JvmtiSuspendControl - see comments in jvmtiImpl.hpp | |
877 // | |
878 | |
879 bool JvmtiSuspendControl::suspend(JavaThread *java_thread) { | |
880 // external suspend should have caught suspending a thread twice | |
881 | |
882 // Immediate suspension required for JPDA back-end so JVMTI agent threads do | |
883 // not deadlock due to later suspension on transitions while holding | |
884 // raw monitors. Passing true causes the immediate suspension. | |
885 // java_suspend() will catch threads in the process of exiting | |
886 // and will ignore them. | |
887 java_thread->java_suspend(); | |
888 | |
889 // It would be nice to have the following assertion in all the time, | |
890 // but it is possible for a racing resume request to have resumed | |
891 // this thread right after we suspended it. Temporarily enable this | |
892 // assertion if you are chasing a different kind of bug. | |
893 // | |
894 // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL || | |
895 // java_thread->is_being_ext_suspended(), "thread is not suspended"); | |
896 | |
897 if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) { | |
898 // check again because we can get delayed in java_suspend(): | |
899 // the thread is in process of exiting. | |
900 return false; | |
901 } | |
902 | |
903 return true; | |
904 } | |
905 | |
906 bool JvmtiSuspendControl::resume(JavaThread *java_thread) { | |
907 // external suspend should have caught resuming a thread twice | |
908 assert(java_thread->is_being_ext_suspended(), "thread should be suspended"); | |
909 | |
910 // resume thread | |
911 { | |
912 // must always grab Threads_lock, see JVM_SuspendThread | |
913 MutexLocker ml(Threads_lock); | |
914 java_thread->java_resume(); | |
915 } | |
916 | |
917 return true; | |
918 } | |
919 | |
920 | |
921 void JvmtiSuspendControl::print() { | |
922 #ifndef PRODUCT | |
923 MutexLocker mu(Threads_lock); | |
924 ResourceMark rm; | |
925 | |
926 tty->print("Suspended Threads: ["); | |
927 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
928 #if JVMTI_TRACE | |
929 const char *name = JvmtiTrace::safe_get_thread_name(thread); | |
930 #else | |
931 const char *name = ""; | |
932 #endif /*JVMTI_TRACE */ | |
933 tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_'); | |
934 if (!thread->has_last_Java_frame()) { | |
935 tty->print("no stack"); | |
936 } | |
937 tty->print(") "); | |
938 } | |
939 tty->print_cr("]"); | |
940 #endif | |
941 } |