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 }