8266497: Remove unnecessary EMCP liveness indication
Reviewed-by: iklam, dholmes, sspitsyn
This commit is contained in:
parent
6ba911d64e
commit
a05e8e2422
@ -3989,30 +3989,6 @@ void InstanceKlass::purge_previous_version_list() {
|
||||
_has_previous_versions = true;
|
||||
}
|
||||
|
||||
// At least one method is live in this previous version.
|
||||
// Reset dead EMCP methods not to get breakpoints.
|
||||
// All methods are deallocated when all of the methods for this class are no
|
||||
// longer running.
|
||||
Array<Method*>* method_refs = pv_node->methods();
|
||||
if (method_refs != NULL) {
|
||||
log_trace(redefine, class, iklass, purge)("previous methods length=%d", method_refs->length());
|
||||
for (int j = 0; j < method_refs->length(); j++) {
|
||||
Method* method = method_refs->at(j);
|
||||
|
||||
if (!method->on_stack()) {
|
||||
// no breakpoints for non-running methods
|
||||
if (method->is_running_emcp()) {
|
||||
method->set_running_emcp(false);
|
||||
}
|
||||
} else {
|
||||
assert (method->is_obsolete() || method->is_running_emcp(),
|
||||
"emcp method cannot run after emcp bit is cleared");
|
||||
log_trace(redefine, class, iklass, purge)
|
||||
("purge: %s(%s): prev method @%d in version @%d is alive",
|
||||
method->name()->as_C_string(), method->signature()->as_C_string(), j, version);
|
||||
}
|
||||
}
|
||||
}
|
||||
// next previous version
|
||||
last = pv_node;
|
||||
pv_node = pv_node->previous_versions();
|
||||
@ -4112,29 +4088,6 @@ void InstanceKlass::add_previous_version(InstanceKlass* scratch_class,
|
||||
return;
|
||||
}
|
||||
|
||||
if (emcp_method_count != 0) {
|
||||
// At least one method is still running, check for EMCP methods
|
||||
for (int i = 0; i < old_methods->length(); i++) {
|
||||
Method* old_method = old_methods->at(i);
|
||||
if (!old_method->is_obsolete() && old_method->on_stack()) {
|
||||
// if EMCP method (not obsolete) is on the stack, mark as EMCP so that
|
||||
// we can add breakpoints for it.
|
||||
|
||||
// We set the method->on_stack bit during safepoints for class redefinition
|
||||
// and use this bit to set the is_running_emcp bit.
|
||||
// After the safepoint, the on_stack bit is cleared and the running emcp
|
||||
// method may exit. If so, we would set a breakpoint in a method that
|
||||
// is never reached, but this won't be noticeable to the programmer.
|
||||
old_method->set_running_emcp(true);
|
||||
log_trace(redefine, class, iklass, add)
|
||||
("EMCP method %s is on_stack " INTPTR_FORMAT, old_method->name_and_sig_as_C_string(), p2i(old_method));
|
||||
} else if (!old_method->is_obsolete()) {
|
||||
log_trace(redefine, class, iklass, add)
|
||||
("EMCP method %s is NOT on_stack " INTPTR_FORMAT, old_method->name_and_sig_as_C_string(), p2i(old_method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add previous version if any methods are still running.
|
||||
// Set has_previous_version flag for processing during class unloading.
|
||||
_has_previous_versions = true;
|
||||
|
@ -2230,8 +2230,6 @@ void Method::set_on_stack(const bool value) {
|
||||
if (value && !already_set) {
|
||||
MetadataOnStackMark::record(this);
|
||||
}
|
||||
assert(!value || !is_old() || is_obsolete() || is_running_emcp(),
|
||||
"emcp methods cannot run after emcp bit is cleared");
|
||||
}
|
||||
|
||||
// Called when the class loader is unloaded to make all methods weak.
|
||||
|
@ -88,10 +88,9 @@ class Method : public Metadata {
|
||||
_dont_inline = 1 << 2,
|
||||
_hidden = 1 << 3,
|
||||
_has_injected_profile = 1 << 4,
|
||||
_running_emcp = 1 << 5,
|
||||
_intrinsic_candidate = 1 << 6,
|
||||
_reserved_stack_access = 1 << 7,
|
||||
_scoped = 1 << 8
|
||||
_intrinsic_candidate = 1 << 5,
|
||||
_reserved_stack_access = 1 << 6,
|
||||
_scoped = 1 << 7
|
||||
};
|
||||
mutable u2 _flags;
|
||||
|
||||
@ -743,20 +742,6 @@ public:
|
||||
bool is_deleted() const { return access_flags().is_deleted(); }
|
||||
void set_is_deleted() { _access_flags.set_is_deleted(); }
|
||||
|
||||
bool is_running_emcp() const {
|
||||
// EMCP methods are old but not obsolete or deleted. Equivalent
|
||||
// Modulo Constant Pool means the method is equivalent except
|
||||
// the constant pool and instructions that access the constant
|
||||
// pool might be different.
|
||||
// If a breakpoint is set in a redefined method, its EMCP methods that are
|
||||
// still running must have a breakpoint also.
|
||||
return (_flags & _running_emcp) != 0;
|
||||
}
|
||||
|
||||
void set_running_emcp(bool x) {
|
||||
_flags = x ? (_flags | _running_emcp) : (_flags & ~_running_emcp);
|
||||
}
|
||||
|
||||
bool on_stack() const { return access_flags().on_stack(); }
|
||||
void set_on_stack(const bool value);
|
||||
|
||||
|
@ -243,8 +243,17 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
|
||||
|
||||
for (int i = methods->length() - 1; i >= 0; i--) {
|
||||
Method* method = methods->at(i);
|
||||
// Only set breakpoints in running EMCP methods.
|
||||
if (method->is_running_emcp() &&
|
||||
// Only set breakpoints in EMCP methods.
|
||||
// EMCP methods are old but not obsolete. Equivalent
|
||||
// Modulo Constant Pool means the method is equivalent except
|
||||
// the constant pool and instructions that access the constant
|
||||
// pool might be different.
|
||||
// If a breakpoint is set in a redefined method, its EMCP methods
|
||||
// must have a breakpoint also.
|
||||
// None of the methods are deleted until none are running.
|
||||
// This code could set a breakpoint in a method that
|
||||
// is never reached, but this won't be noticeable to the programmer.
|
||||
if (!method->is_obsolete() &&
|
||||
method->name() == m_name &&
|
||||
method->signature() == m_signature) {
|
||||
ResourceMark rm;
|
||||
|
Loading…
Reference in New Issue
Block a user