Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiImpl.hpp @ 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 | f2110083203d |
children | 77b028ba548c |
comparison
equal
deleted
inserted
replaced
13037:c8fc12209830 | 13038:910026b800b8 |
---|---|
67 virtual address getCacheValue() =0; | 67 virtual address getCacheValue() =0; |
68 virtual bool equals(GrowableElement* e) =0; | 68 virtual bool equals(GrowableElement* e) =0; |
69 virtual bool lessThan(GrowableElement *e)=0; | 69 virtual bool lessThan(GrowableElement *e)=0; |
70 virtual GrowableElement *clone() =0; | 70 virtual GrowableElement *clone() =0; |
71 virtual void oops_do(OopClosure* f) =0; | 71 virtual void oops_do(OopClosure* f) =0; |
72 virtual void metadata_do(void f(Metadata*)) =0; | |
72 }; | 73 }; |
73 | 74 |
74 class GrowableCache VALUE_OBJ_CLASS_SPEC { | 75 class GrowableCache VALUE_OBJ_CLASS_SPEC { |
75 | 76 |
76 private: | 77 private: |
113 void remove (int index); | 114 void remove (int index); |
114 // clear out all elements and release all heap space, notify listener | 115 // clear out all elements and release all heap space, notify listener |
115 void clear(); | 116 void clear(); |
116 // apply f to every element and update the cache | 117 // apply f to every element and update the cache |
117 void oops_do(OopClosure* f); | 118 void oops_do(OopClosure* f); |
119 // walk metadata to preserve for RedefineClasses | |
120 void metadata_do(void f(Metadata*)); | |
118 // update the cache after a full gc | 121 // update the cache after a full gc |
119 void gc_epilogue(); | 122 void gc_epilogue(); |
120 }; | 123 }; |
121 | 124 |
122 | 125 |
146 int find(JvmtiBreakpoint& e) { return _cache.find((GrowableElement *) &e); } | 149 int find(JvmtiBreakpoint& e) { return _cache.find((GrowableElement *) &e); } |
147 void append(JvmtiBreakpoint& e) { _cache.append((GrowableElement *) &e); } | 150 void append(JvmtiBreakpoint& e) { _cache.append((GrowableElement *) &e); } |
148 void remove (int index) { _cache.remove(index); } | 151 void remove (int index) { _cache.remove(index); } |
149 void clear() { _cache.clear(); } | 152 void clear() { _cache.clear(); } |
150 void oops_do(OopClosure* f) { _cache.oops_do(f); } | 153 void oops_do(OopClosure* f) { _cache.oops_do(f); } |
154 void metadata_do(void f(Metadata*)) { _cache.metadata_do(f); } | |
151 void gc_epilogue() { _cache.gc_epilogue(); } | 155 void gc_epilogue() { _cache.gc_epilogue(); } |
152 }; | 156 }; |
153 | 157 |
154 | 158 |
155 /////////////////////////////////////////////////////////////// | 159 /////////////////////////////////////////////////////////////// |
167 class JvmtiBreakpoint : public GrowableElement { | 171 class JvmtiBreakpoint : public GrowableElement { |
168 private: | 172 private: |
169 Method* _method; | 173 Method* _method; |
170 int _bci; | 174 int _bci; |
171 Bytecodes::Code _orig_bytecode; | 175 Bytecodes::Code _orig_bytecode; |
172 oop _class_loader; | 176 oop _class_holder; // keeps _method memory from being deallocated |
173 | 177 |
174 public: | 178 public: |
175 JvmtiBreakpoint(); | 179 JvmtiBreakpoint(); |
176 JvmtiBreakpoint(Method* m_method, jlocation location); | 180 JvmtiBreakpoint(Method* m_method, jlocation location); |
177 bool equals(JvmtiBreakpoint& bp); | 181 bool equals(JvmtiBreakpoint& bp); |
189 // GrowableElement implementation | 193 // GrowableElement implementation |
190 address getCacheValue() { return getBcp(); } | 194 address getCacheValue() { return getBcp(); } |
191 bool lessThan(GrowableElement* e) { Unimplemented(); return false; } | 195 bool lessThan(GrowableElement* e) { Unimplemented(); return false; } |
192 bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); } | 196 bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); } |
193 void oops_do(OopClosure* f) { | 197 void oops_do(OopClosure* f) { |
194 // Mark the method loader as live | 198 // Mark the method loader as live so the Method* class loader doesn't get |
195 f->do_oop(&_class_loader); | 199 // unloaded and Method* memory reclaimed. |
200 f->do_oop(&_class_holder); | |
196 } | 201 } |
202 void metadata_do(void f(Metadata*)) { | |
203 // walk metadata to preserve for RedefineClasses | |
204 f(_method); | |
205 } | |
206 | |
197 GrowableElement *clone() { | 207 GrowableElement *clone() { |
198 JvmtiBreakpoint *bp = new JvmtiBreakpoint(); | 208 JvmtiBreakpoint *bp = new JvmtiBreakpoint(); |
199 bp->copy(*this); | 209 bp->copy(*this); |
200 return bp; | 210 return bp; |
201 } | 211 } |
237 JvmtiBreakpoints(void listener_fun(void *, address *)); | 247 JvmtiBreakpoints(void listener_fun(void *, address *)); |
238 ~JvmtiBreakpoints(); | 248 ~JvmtiBreakpoints(); |
239 | 249 |
240 int length(); | 250 int length(); |
241 void oops_do(OopClosure* f); | 251 void oops_do(OopClosure* f); |
252 void metadata_do(void f(Metadata*)); | |
242 void print(); | 253 void print(); |
243 | 254 |
244 int set(JvmtiBreakpoint& bp); | 255 int set(JvmtiBreakpoint& bp); |
245 int clear(JvmtiBreakpoint& bp); | 256 int clear(JvmtiBreakpoint& bp); |
246 void clearall_in_class_at_safepoint(Klass* klass); | 257 void clearall_in_class_at_safepoint(Klass* klass); |
286 | 297 |
287 // quickly test whether the bcp matches a cached breakpoint in the list | 298 // quickly test whether the bcp matches a cached breakpoint in the list |
288 static inline bool is_breakpoint(address bcp); | 299 static inline bool is_breakpoint(address bcp); |
289 | 300 |
290 static void oops_do(OopClosure* f); | 301 static void oops_do(OopClosure* f); |
302 static void metadata_do(void f(Metadata*)); | |
291 static void gc_epilogue(); | 303 static void gc_epilogue(); |
292 }; | 304 }; |
293 | 305 |
294 // quickly test whether the bcp matches a cached breakpoint in the list | 306 // quickly test whether the bcp matches a cached breakpoint in the list |
295 bool JvmtiCurrentBreakpoints::is_breakpoint(address bcp) { | 307 bool JvmtiCurrentBreakpoints::is_breakpoint(address bcp) { |
330 } | 342 } |
331 | 343 |
332 VMOp_Type type() const { return VMOp_ChangeBreakpoints; } | 344 VMOp_Type type() const { return VMOp_ChangeBreakpoints; } |
333 void doit(); | 345 void doit(); |
334 void oops_do(OopClosure* f); | 346 void oops_do(OopClosure* f); |
347 void metadata_do(void f(Metadata*)); | |
335 }; | 348 }; |
336 | 349 |
337 | 350 |
338 /////////////////////////////////////////////////////////////// | 351 /////////////////////////////////////////////////////////////// |
339 // The get/set local operations must only be done by the VM thread | 352 // The get/set local operations must only be done by the VM thread |