diff 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
line wrap: on
line diff
--- a/src/share/vm/prims/jvmtiImpl.cpp	Thu Oct 31 14:11:02 2013 -0400
+++ b/src/share/vm/prims/jvmtiImpl.cpp	Fri Nov 01 10:32:36 2013 -0400
@@ -210,6 +210,14 @@
   }
 }
 
+void GrowableCache::metadata_do(void f(Metadata*)) {
+  int len = _elements->length();
+  for (int i=0; i<len; i++) {
+    GrowableElement *e = _elements->at(i);
+    e->metadata_do(f);
+  }
+}
+
 void GrowableCache::gc_epilogue() {
   int len = _elements->length();
   for (int i=0; i<len; i++) {
@@ -224,20 +232,20 @@
 JvmtiBreakpoint::JvmtiBreakpoint() {
   _method = NULL;
   _bci    = 0;
-  _class_loader = NULL;
+  _class_holder = NULL;
 }
 
 JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {
   _method        = m_method;
-  _class_loader  = _method->method_holder()->class_loader_data()->class_loader();
+  _class_holder  = _method->method_holder()->klass_holder();
 #ifdef CHECK_UNHANDLED_OOPS
-  // _class_loader can't be wrapped in a Handle, because JvmtiBreakpoint:s are
-  // eventually allocated on the heap.
+  // _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are
+  // sometimes allocated on the heap.
   //
-  // The code handling JvmtiBreakpoint:s allocated on the stack can't be
-  // interrupted by a GC until _class_loader is reachable by the GC via the
+  // The code handling JvmtiBreakpoints allocated on the stack can't be
+  // interrupted by a GC until _class_holder is reachable by the GC via the
   // oops_do method.
-  Thread::current()->allow_unhandled_oop(&_class_loader);
+  Thread::current()->allow_unhandled_oop(&_class_holder);
 #endif // CHECK_UNHANDLED_OOPS
   assert(_method != NULL, "_method != NULL");
   _bci           = (int) location;
@@ -247,7 +255,7 @@
 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
   _method   = bp._method;
   _bci      = bp._bci;
-  _class_loader = bp._class_loader;
+  _class_holder = bp._class_holder;
 }
 
 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
@@ -365,6 +373,13 @@
   }
 }
 
+void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) {
+  // Walk metadata in breakpoints to keep from being deallocated with RedefineClasses
+  if (_bp != NULL) {
+    _bp->metadata_do(f);
+  }
+}
+
 //
 // class JvmtiBreakpoints
 //
@@ -381,6 +396,10 @@
   _bps.oops_do(f);
 }
 
+void  JvmtiBreakpoints::metadata_do(void f(Metadata*)) {
+  _bps.metadata_do(f);
+}
+
 void JvmtiBreakpoints::gc_epilogue() {
   _bps.gc_epilogue();
 }
@@ -499,6 +518,12 @@
   }
 }
 
+void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {
+  if (_jvmti_breakpoints != NULL) {
+    _jvmti_breakpoints->metadata_do(f);
+  }
+}
+
 void JvmtiCurrentBreakpoints::gc_epilogue() {
   if (_jvmti_breakpoints != NULL) {
     _jvmti_breakpoints->gc_epilogue();