Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiImpl.cpp @ 12281:4f9a42c33738
8022887: Assertion hit while using class and redefining it with RedefineClasses simultaneously
Summary: Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code.
Reviewed-by: dcubed, sspitsyn
author | coleenp |
---|---|
date | Fri, 20 Sep 2013 09:30:02 -0400 |
parents | f2110083203d |
children | cefad50507d8 2fab5b7e6140 |
comparison
equal
deleted
inserted
replaced
12279:6eb908998b32 | 12281:4f9a42c33738 |
---|---|
271 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { | 271 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { |
272 ((Method*)_method->*meth_act)(_bci); | 272 ((Method*)_method->*meth_act)(_bci); |
273 | 273 |
274 // add/remove breakpoint to/from versions of the method that | 274 // add/remove breakpoint to/from versions of the method that |
275 // are EMCP. Directly or transitively obsolete methods are | 275 // are EMCP. Directly or transitively obsolete methods are |
276 // not saved in the PreviousVersionInfo. | 276 // not saved in the PreviousVersionNodes. |
277 Thread *thread = Thread::current(); | 277 Thread *thread = Thread::current(); |
278 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); | 278 instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); |
279 Symbol* m_name = _method->name(); | 279 Symbol* m_name = _method->name(); |
280 Symbol* m_signature = _method->signature(); | 280 Symbol* m_signature = _method->signature(); |
281 | 281 |
282 { | 282 // search previous versions if they exist |
283 ResourceMark rm(thread); | 283 PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh()); |
284 // PreviousVersionInfo objects returned via PreviousVersionWalker | 284 for (PreviousVersionNode * pv_node = pvw.next_previous_version(); |
285 // contain a GrowableArray of handles. We have to clean up the | 285 pv_node != NULL; pv_node = pvw.next_previous_version()) { |
286 // GrowableArray _after_ the PreviousVersionWalker destructor | 286 GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods(); |
287 // has destroyed the handles. | 287 |
288 { | 288 if (methods == NULL) { |
289 // search previous versions if they exist | 289 // We have run into a PreviousVersion generation where |
290 PreviousVersionWalker pvw((InstanceKlass *)ikh()); | 290 // all methods were made obsolete during that generation's |
291 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | 291 // RedefineClasses() operation. At the time of that |
292 pv_info != NULL; pv_info = pvw.next_previous_version()) { | 292 // operation, all EMCP methods were flushed so we don't |
293 GrowableArray<methodHandle>* methods = | 293 // have to go back any further. |
294 pv_info->prev_EMCP_method_handles(); | 294 // |
295 | 295 // A NULL methods array is different than an empty methods |
296 if (methods == NULL) { | 296 // array. We cannot infer any optimizations about older |
297 // We have run into a PreviousVersion generation where | 297 // generations from an empty methods array for the current |
298 // all methods were made obsolete during that generation's | 298 // generation. |
299 // RedefineClasses() operation. At the time of that | 299 break; |
300 // operation, all EMCP methods were flushed so we don't | 300 } |
301 // have to go back any further. | 301 |
302 // | 302 for (int i = methods->length() - 1; i >= 0; i--) { |
303 // A NULL methods array is different than an empty methods | 303 Method* method = methods->at(i); |
304 // array. We cannot infer any optimizations about older | 304 // obsolete methods that are running are not deleted from |
305 // generations from an empty methods array for the current | 305 // previous version array, but they are skipped here. |
306 // generation. | 306 if (!method->is_obsolete() && |
307 break; | 307 method->name() == m_name && |
308 } | 308 method->signature() == m_signature) { |
309 | 309 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", |
310 for (int i = methods->length() - 1; i >= 0; i--) { | 310 meth_act == &Method::set_breakpoint ? "sett" : "clear", |
311 methodHandle method = methods->at(i); | 311 method->name()->as_C_string(), |
312 // obsolete methods that are running are not deleted from | 312 method->signature()->as_C_string())); |
313 // previous version array, but they are skipped here. | 313 |
314 if (!method->is_obsolete() && | 314 (method->*meth_act)(_bci); |
315 method->name() == m_name && | 315 break; |
316 method->signature() == m_signature) { | |
317 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", | |
318 meth_act == &Method::set_breakpoint ? "sett" : "clear", | |
319 method->name()->as_C_string(), | |
320 method->signature()->as_C_string())); | |
321 | |
322 ((Method*)method()->*meth_act)(_bci); | |
323 break; | |
324 } | |
325 } | |
326 } | 316 } |
327 } // pvw is cleaned up | 317 } |
328 } // rm is cleaned up | 318 } |
329 } | 319 } |
330 | 320 |
331 void JvmtiBreakpoint::set() { | 321 void JvmtiBreakpoint::set() { |
332 each_method_version_do(&Method::set_breakpoint); | 322 each_method_version_do(&Method::set_breakpoint); |
333 } | 323 } |