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;
|
_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
|
// next previous version
|
||||||
last = pv_node;
|
last = pv_node;
|
||||||
pv_node = pv_node->previous_versions();
|
pv_node = pv_node->previous_versions();
|
||||||
@ -4112,29 +4088,6 @@ void InstanceKlass::add_previous_version(InstanceKlass* scratch_class,
|
|||||||
return;
|
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.
|
// Add previous version if any methods are still running.
|
||||||
// Set has_previous_version flag for processing during class unloading.
|
// Set has_previous_version flag for processing during class unloading.
|
||||||
_has_previous_versions = true;
|
_has_previous_versions = true;
|
||||||
|
@ -2230,8 +2230,6 @@ void Method::set_on_stack(const bool value) {
|
|||||||
if (value && !already_set) {
|
if (value && !already_set) {
|
||||||
MetadataOnStackMark::record(this);
|
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.
|
// Called when the class loader is unloaded to make all methods weak.
|
||||||
|
@ -88,10 +88,9 @@ class Method : public Metadata {
|
|||||||
_dont_inline = 1 << 2,
|
_dont_inline = 1 << 2,
|
||||||
_hidden = 1 << 3,
|
_hidden = 1 << 3,
|
||||||
_has_injected_profile = 1 << 4,
|
_has_injected_profile = 1 << 4,
|
||||||
_running_emcp = 1 << 5,
|
_intrinsic_candidate = 1 << 5,
|
||||||
_intrinsic_candidate = 1 << 6,
|
_reserved_stack_access = 1 << 6,
|
||||||
_reserved_stack_access = 1 << 7,
|
_scoped = 1 << 7
|
||||||
_scoped = 1 << 8
|
|
||||||
};
|
};
|
||||||
mutable u2 _flags;
|
mutable u2 _flags;
|
||||||
|
|
||||||
@ -743,20 +742,6 @@ public:
|
|||||||
bool is_deleted() const { return access_flags().is_deleted(); }
|
bool is_deleted() const { return access_flags().is_deleted(); }
|
||||||
void set_is_deleted() { _access_flags.set_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(); }
|
bool on_stack() const { return access_flags().on_stack(); }
|
||||||
void set_on_stack(const bool value);
|
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--) {
|
for (int i = methods->length() - 1; i >= 0; i--) {
|
||||||
Method* method = methods->at(i);
|
Method* method = methods->at(i);
|
||||||
// Only set breakpoints in running EMCP methods.
|
// Only set breakpoints in EMCP methods.
|
||||||
if (method->is_running_emcp() &&
|
// 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->name() == m_name &&
|
||||||
method->signature() == m_signature) {
|
method->signature() == m_signature) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
Loading…
Reference in New Issue
Block a user