comparison src/share/vm/prims/jvmtiImpl.cpp @ 13038:910026b800b8

8026946: JvmtiEnv::SetBreakpoint and JvmtiEnv::ClearBreakpoint should use MethodHandle 8026948: JvmtiEnv::SetBreakpoint and JvmtiEnv::ClearBreakpoint might not work with anonymous classes Summary: Walk methods in breakpoints for marking on stack so they aren't deallocated by redefine classes. Use class_holder rather than class_loader to keep GC from reclaiming class owning the method. Reviewed-by: sspitsyn, ehelin, sla
author coleenp
date Fri, 01 Nov 2013 10:32:36 -0400
parents 2fab5b7e6140
children 096c224171c4 78bbf4d43a14
comparison
equal deleted inserted replaced
13037:c8fc12209830 13038:910026b800b8
208 GrowableElement *e = _elements->at(i); 208 GrowableElement *e = _elements->at(i);
209 e->oops_do(f); 209 e->oops_do(f);
210 } 210 }
211 } 211 }
212 212
213 void GrowableCache::metadata_do(void f(Metadata*)) {
214 int len = _elements->length();
215 for (int i=0; i<len; i++) {
216 GrowableElement *e = _elements->at(i);
217 e->metadata_do(f);
218 }
219 }
220
213 void GrowableCache::gc_epilogue() { 221 void GrowableCache::gc_epilogue() {
214 int len = _elements->length(); 222 int len = _elements->length();
215 for (int i=0; i<len; i++) { 223 for (int i=0; i<len; i++) {
216 _cache[i] = _elements->at(i)->getCacheValue(); 224 _cache[i] = _elements->at(i)->getCacheValue();
217 } 225 }
222 // 230 //
223 231
224 JvmtiBreakpoint::JvmtiBreakpoint() { 232 JvmtiBreakpoint::JvmtiBreakpoint() {
225 _method = NULL; 233 _method = NULL;
226 _bci = 0; 234 _bci = 0;
227 _class_loader = NULL; 235 _class_holder = NULL;
228 } 236 }
229 237
230 JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) { 238 JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {
231 _method = m_method; 239 _method = m_method;
232 _class_loader = _method->method_holder()->class_loader_data()->class_loader(); 240 _class_holder = _method->method_holder()->klass_holder();
233 #ifdef CHECK_UNHANDLED_OOPS 241 #ifdef CHECK_UNHANDLED_OOPS
234 // _class_loader can't be wrapped in a Handle, because JvmtiBreakpoint:s are 242 // _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are
235 // eventually allocated on the heap. 243 // sometimes allocated on the heap.
236 // 244 //
237 // The code handling JvmtiBreakpoint:s allocated on the stack can't be 245 // The code handling JvmtiBreakpoints allocated on the stack can't be
238 // interrupted by a GC until _class_loader is reachable by the GC via the 246 // interrupted by a GC until _class_holder is reachable by the GC via the
239 // oops_do method. 247 // oops_do method.
240 Thread::current()->allow_unhandled_oop(&_class_loader); 248 Thread::current()->allow_unhandled_oop(&_class_holder);
241 #endif // CHECK_UNHANDLED_OOPS 249 #endif // CHECK_UNHANDLED_OOPS
242 assert(_method != NULL, "_method != NULL"); 250 assert(_method != NULL, "_method != NULL");
243 _bci = (int) location; 251 _bci = (int) location;
244 assert(_bci >= 0, "_bci >= 0"); 252 assert(_bci >= 0, "_bci >= 0");
245 } 253 }
246 254
247 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { 255 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
248 _method = bp._method; 256 _method = bp._method;
249 _bci = bp._bci; 257 _bci = bp._bci;
250 _class_loader = bp._class_loader; 258 _class_holder = bp._class_holder;
251 } 259 }
252 260
253 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { 261 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
254 Unimplemented(); 262 Unimplemented();
255 return false; 263 return false;
363 if (_bp != NULL) { 371 if (_bp != NULL) {
364 _bp->oops_do(f); 372 _bp->oops_do(f);
365 } 373 }
366 } 374 }
367 375
376 void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) {
377 // Walk metadata in breakpoints to keep from being deallocated with RedefineClasses
378 if (_bp != NULL) {
379 _bp->metadata_do(f);
380 }
381 }
382
368 // 383 //
369 // class JvmtiBreakpoints 384 // class JvmtiBreakpoints
370 // 385 //
371 // a JVMTI internal collection of JvmtiBreakpoint 386 // a JVMTI internal collection of JvmtiBreakpoint
372 // 387 //
377 392
378 JvmtiBreakpoints:: ~JvmtiBreakpoints() {} 393 JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
379 394
380 void JvmtiBreakpoints::oops_do(OopClosure* f) { 395 void JvmtiBreakpoints::oops_do(OopClosure* f) {
381 _bps.oops_do(f); 396 _bps.oops_do(f);
397 }
398
399 void JvmtiBreakpoints::metadata_do(void f(Metadata*)) {
400 _bps.metadata_do(f);
382 } 401 }
383 402
384 void JvmtiBreakpoints::gc_epilogue() { 403 void JvmtiBreakpoints::gc_epilogue() {
385 _bps.gc_epilogue(); 404 _bps.gc_epilogue();
386 } 405 }
497 if (_jvmti_breakpoints != NULL) { 516 if (_jvmti_breakpoints != NULL) {
498 _jvmti_breakpoints->oops_do(f); 517 _jvmti_breakpoints->oops_do(f);
499 } 518 }
500 } 519 }
501 520
521 void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {
522 if (_jvmti_breakpoints != NULL) {
523 _jvmti_breakpoints->metadata_do(f);
524 }
525 }
526
502 void JvmtiCurrentBreakpoints::gc_epilogue() { 527 void JvmtiCurrentBreakpoints::gc_epilogue() {
503 if (_jvmti_breakpoints != NULL) { 528 if (_jvmti_breakpoints != NULL) {
504 _jvmti_breakpoints->gc_epilogue(); 529 _jvmti_breakpoints->gc_epilogue();
505 } 530 }
506 } 531 }