8235912: JvmtiBreakpoint remove oops_do and metadata_do
Reviewed-by: coleenp, sspitsyn
This commit is contained in:
parent
18bc0214db
commit
e4c96dea46
@ -70,7 +70,6 @@ MetadataOnStackMark::MetadataOnStackMark(bool walk_all_metadata, bool redefiniti
|
||||
CodeCache::old_nmethods_do(&md_on_stack);
|
||||
}
|
||||
CompileBroker::mark_on_stack();
|
||||
JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
|
||||
ThreadService::metadata_do(Metadata::mark_on_stack);
|
||||
#if INCLUDE_JVMCI
|
||||
JVMCI::metadata_do(Metadata::mark_on_stack);
|
||||
|
@ -2600,7 +2600,6 @@ void JvmtiExport::clear_detected_exception(JavaThread* thread) {
|
||||
}
|
||||
|
||||
void JvmtiExport::oops_do(OopClosure* f) {
|
||||
JvmtiCurrentBreakpoints::oops_do(f);
|
||||
JvmtiObjectAllocEventCollector::oops_do_for_all_threads(f);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "gc/shared/oopStorage.hpp"
|
||||
#include "gc/shared/oopStorageSet.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "jvmtifiles/jvmtiEnv.hpp"
|
||||
@ -171,24 +173,6 @@ void GrowableCache::append(GrowableElement* e) {
|
||||
recache();
|
||||
}
|
||||
|
||||
// insert a copy of the element using lessthan()
|
||||
void GrowableCache::insert(GrowableElement* e) {
|
||||
GrowableElement *new_e = e->clone();
|
||||
_elements->append(new_e);
|
||||
|
||||
int n = length()-2;
|
||||
for (int i=n; i>=0; i--) {
|
||||
GrowableElement *e1 = _elements->at(i);
|
||||
GrowableElement *e2 = _elements->at(i+1);
|
||||
if (e2->lessThan(e1)) {
|
||||
_elements->at_put(i+1, e1);
|
||||
_elements->at_put(i, e2);
|
||||
}
|
||||
}
|
||||
|
||||
recache();
|
||||
}
|
||||
|
||||
// remove the element at index
|
||||
void GrowableCache::remove (int index) {
|
||||
GrowableElement *e = _elements->at(index);
|
||||
@ -209,58 +193,40 @@ void GrowableCache::clear() {
|
||||
recache();
|
||||
}
|
||||
|
||||
void GrowableCache::oops_do(OopClosure* f) {
|
||||
int len = _elements->length();
|
||||
for (int i=0; i<len; i++) {
|
||||
GrowableElement *e = _elements->at(i);
|
||||
e->oops_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// class JvmtiBreakpoint
|
||||
//
|
||||
|
||||
JvmtiBreakpoint::JvmtiBreakpoint() {
|
||||
_method = NULL;
|
||||
_bci = 0;
|
||||
_class_holder = NULL;
|
||||
JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location)
|
||||
: _method(m_method), _bci((int)location), _class_holder(NULL) {
|
||||
assert(_method != NULL, "No method for breakpoint.");
|
||||
assert(_bci >= 0, "Negative bci for breakpoint.");
|
||||
oop class_holder_oop = _method->method_holder()->klass_holder();
|
||||
_class_holder = OopStorageSet::vm_global()->allocate();
|
||||
if (_class_holder == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
|
||||
"Cannot create breakpoint oop handle");
|
||||
}
|
||||
NativeAccess<>::oop_store(_class_holder, class_holder_oop);
|
||||
}
|
||||
|
||||
JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {
|
||||
_method = m_method;
|
||||
_class_holder = _method->method_holder()->klass_holder();
|
||||
#ifdef CHECK_UNHANDLED_OOPS
|
||||
// _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are
|
||||
// sometimes allocated on the heap.
|
||||
//
|
||||
// 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_holder);
|
||||
#endif // CHECK_UNHANDLED_OOPS
|
||||
assert(_method != NULL, "_method != NULL");
|
||||
_bci = (int) location;
|
||||
assert(_bci >= 0, "_bci >= 0");
|
||||
JvmtiBreakpoint::~JvmtiBreakpoint() {
|
||||
if (_class_holder != NULL) {
|
||||
NativeAccess<>::oop_store(_class_holder, (oop)NULL);
|
||||
OopStorageSet::vm_global()->release(_class_holder);
|
||||
}
|
||||
}
|
||||
|
||||
void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
|
||||
_method = bp._method;
|
||||
_bci = bp._bci;
|
||||
_class_holder = bp._class_holder;
|
||||
}
|
||||
|
||||
bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
|
||||
Unimplemented();
|
||||
return false;
|
||||
_class_holder = OopStorageSet::vm_global()->allocate();
|
||||
if (_class_holder == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
|
||||
"Cannot create breakpoint oop handle");
|
||||
}
|
||||
oop resolved_ch = NativeAccess<>::oop_load(bp._class_holder);
|
||||
NativeAccess<>::oop_store(_class_holder, resolved_ch);
|
||||
}
|
||||
|
||||
bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
|
||||
@ -268,12 +234,6 @@ bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
|
||||
&& _bci == bp._bci;
|
||||
}
|
||||
|
||||
bool JvmtiBreakpoint::is_valid() {
|
||||
// class loader can be NULL
|
||||
return _method != NULL &&
|
||||
_bci >= 0;
|
||||
}
|
||||
|
||||
address JvmtiBreakpoint::getBcp() const {
|
||||
return _method->bcp_from(_bci);
|
||||
}
|
||||
@ -347,21 +307,6 @@ void VM_ChangeBreakpoints::doit() {
|
||||
}
|
||||
}
|
||||
|
||||
void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
|
||||
// The JvmtiBreakpoints in _breakpoints will be visited via
|
||||
// JvmtiExport::oops_do.
|
||||
if (_bp != NULL) {
|
||||
_bp->oops_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
@ -374,14 +319,6 @@ JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {
|
||||
|
||||
JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
|
||||
|
||||
void JvmtiBreakpoints::oops_do(OopClosure* f) {
|
||||
_bps.oops_do(f);
|
||||
}
|
||||
|
||||
void JvmtiBreakpoints::metadata_do(void f(Metadata*)) {
|
||||
_bps.metadata_do(f);
|
||||
}
|
||||
|
||||
void JvmtiBreakpoints::print() {
|
||||
#ifndef PRODUCT
|
||||
LogTarget(Trace, jvmti) log;
|
||||
@ -490,19 +427,6 @@ void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {
|
||||
set_breakpoint_list(cache);
|
||||
}
|
||||
|
||||
|
||||
void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
|
||||
if (_jvmti_breakpoints != NULL) {
|
||||
_jvmti_breakpoints->oops_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {
|
||||
if (_jvmti_breakpoints != NULL) {
|
||||
_jvmti_breakpoints->metadata_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// class VM_GetOrSetLocal
|
||||
|
@ -68,10 +68,7 @@ public:
|
||||
virtual ~GrowableElement() {}
|
||||
virtual address getCacheValue() =0;
|
||||
virtual bool equals(GrowableElement* e) =0;
|
||||
virtual bool lessThan(GrowableElement *e)=0;
|
||||
virtual GrowableElement *clone() =0;
|
||||
virtual void oops_do(OopClosure* f) =0;
|
||||
virtual void metadata_do(void f(Metadata*)) =0;
|
||||
};
|
||||
|
||||
class GrowableCache {
|
||||
@ -110,16 +107,10 @@ public:
|
||||
int find(GrowableElement* e);
|
||||
// append a copy of the element to the end of the collection, notify listener
|
||||
void append(GrowableElement* e);
|
||||
// insert a copy of the element using lessthan(), notify listener
|
||||
void insert(GrowableElement* e);
|
||||
// remove the element at index, notify listener
|
||||
void remove (int index);
|
||||
// clear out all elements and release all heap space, notify listener
|
||||
void clear();
|
||||
// apply f to every element and update the cache
|
||||
void oops_do(OopClosure* f);
|
||||
// walk metadata to preserve for RedefineClasses
|
||||
void metadata_do(void f(Metadata*));
|
||||
};
|
||||
|
||||
|
||||
@ -141,7 +132,7 @@ public:
|
||||
~JvmtiBreakpointCache() {}
|
||||
|
||||
void initialize(void *this_obj, void listener_fun(void *, address*) ) {
|
||||
_cache.initialize(this_obj,listener_fun);
|
||||
_cache.initialize(this_obj, listener_fun);
|
||||
}
|
||||
|
||||
int length() { return _cache.length(); }
|
||||
@ -149,9 +140,6 @@ public:
|
||||
int find(JvmtiBreakpoint& e) { return _cache.find((GrowableElement *) &e); }
|
||||
void append(JvmtiBreakpoint& e) { _cache.append((GrowableElement *) &e); }
|
||||
void remove (int index) { _cache.remove(index); }
|
||||
void clear() { _cache.clear(); }
|
||||
void oops_do(OopClosure* f) { _cache.oops_do(f); }
|
||||
void metadata_do(void f(Metadata*)) { _cache.metadata_do(f); }
|
||||
};
|
||||
|
||||
|
||||
@ -171,16 +159,14 @@ class JvmtiBreakpoint : public GrowableElement {
|
||||
private:
|
||||
Method* _method;
|
||||
int _bci;
|
||||
Bytecodes::Code _orig_bytecode;
|
||||
oop _class_holder; // keeps _method memory from being deallocated
|
||||
oop* _class_holder; // keeps _method memory from being deallocated
|
||||
|
||||
public:
|
||||
JvmtiBreakpoint();
|
||||
JvmtiBreakpoint() : _method(NULL), _bci(0), _class_holder(NULL) {}
|
||||
JvmtiBreakpoint(Method* m_method, jlocation location);
|
||||
virtual ~JvmtiBreakpoint();
|
||||
bool equals(JvmtiBreakpoint& bp);
|
||||
bool lessThan(JvmtiBreakpoint &bp);
|
||||
void copy(JvmtiBreakpoint& bp);
|
||||
bool is_valid();
|
||||
address getBcp() const;
|
||||
void each_method_version_do(method_action meth_act);
|
||||
void set();
|
||||
@ -191,17 +177,7 @@ public:
|
||||
|
||||
// GrowableElement implementation
|
||||
address getCacheValue() { return getBcp(); }
|
||||
bool lessThan(GrowableElement* e) { Unimplemented(); return false; }
|
||||
bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); }
|
||||
void oops_do(OopClosure* f) {
|
||||
// Mark the method loader as live so the Method* class loader doesn't get
|
||||
// unloaded and Method* memory reclaimed.
|
||||
f->do_oop(&_class_holder);
|
||||
}
|
||||
void metadata_do(void f(Metadata*)) {
|
||||
// walk metadata to preserve for RedefineClasses
|
||||
f(_method);
|
||||
}
|
||||
|
||||
GrowableElement *clone() {
|
||||
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
|
||||
@ -240,15 +216,11 @@ private:
|
||||
void set_at_safepoint(JvmtiBreakpoint& bp);
|
||||
void clear_at_safepoint(JvmtiBreakpoint& bp);
|
||||
|
||||
static void do_element(GrowableElement *e);
|
||||
|
||||
public:
|
||||
JvmtiBreakpoints(void listener_fun(void *, address *));
|
||||
~JvmtiBreakpoints();
|
||||
|
||||
int length();
|
||||
void oops_do(OopClosure* f);
|
||||
void metadata_do(void f(Metadata*));
|
||||
void print();
|
||||
|
||||
int set(JvmtiBreakpoint& bp);
|
||||
@ -281,7 +253,6 @@ private:
|
||||
// It exists only to make is_breakpoint fast.
|
||||
static address *_breakpoint_list;
|
||||
static inline void set_breakpoint_list(address *breakpoint_list) { _breakpoint_list = breakpoint_list; }
|
||||
static inline address *get_breakpoint_list() { return _breakpoint_list; }
|
||||
|
||||
// Listener for the GrowableCache in _jvmti_breakpoints, updates _breakpoint_list.
|
||||
static void listener_fun(void *this_obj, address *cache);
|
||||
@ -292,9 +263,6 @@ public:
|
||||
|
||||
// lazily create _jvmti_breakpoints and _breakpoint_list
|
||||
static JvmtiBreakpoints& get_jvmti_breakpoints();
|
||||
|
||||
static void oops_do(OopClosure* f);
|
||||
static void metadata_do(void f(Metadata*)) NOT_JVMTI_RETURN;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
@ -326,8 +294,6 @@ public:
|
||||
|
||||
VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
|
||||
void doit();
|
||||
void oops_do(OopClosure* f);
|
||||
void metadata_do(void f(Metadata*));
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user