mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8209624: [JVMCI] Invalidate nmethods instead of directly unloading them when the InstalledCode is dropped
Reviewed-by: kvn
This commit is contained in:
parent
4ef5590fa7
commit
9c4f2b7294
5 changed files with 30 additions and 20 deletions
|
@ -362,7 +362,7 @@ void AOTCompiledMethod::log_identity(xmlStream* log) const {
|
||||||
log->print(" aot='%2d'", _heap->dso_id());
|
log->print(" aot='%2d'", _heap->dso_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOTCompiledMethod::log_state_change() const {
|
void AOTCompiledMethod::log_state_change(oop cause) const {
|
||||||
if (LogCompilation) {
|
if (LogCompilation) {
|
||||||
ResourceMark m;
|
ResourceMark m;
|
||||||
if (xtty != NULL) {
|
if (xtty != NULL) {
|
||||||
|
|
|
@ -193,7 +193,7 @@ private:
|
||||||
virtual int comp_level() const { return CompLevel_aot; }
|
virtual int comp_level() const { return CompLevel_aot; }
|
||||||
virtual address verified_entry_point() const { return _code + _meta->verified_entry_offset(); }
|
virtual address verified_entry_point() const { return _code + _meta->verified_entry_offset(); }
|
||||||
virtual void log_identity(xmlStream* stream) const;
|
virtual void log_identity(xmlStream* stream) const;
|
||||||
virtual void log_state_change() const;
|
virtual void log_state_change(oop cause = NULL) const;
|
||||||
virtual bool make_entrant() NOT_TIERED({ ShouldNotReachHere(); return false; });
|
virtual bool make_entrant() NOT_TIERED({ ShouldNotReachHere(); return false; });
|
||||||
virtual bool make_not_entrant() { return make_not_entrant_helper(not_entrant); }
|
virtual bool make_not_entrant() { return make_not_entrant_helper(not_entrant); }
|
||||||
virtual bool make_not_used() { return make_not_entrant_helper(not_used); }
|
virtual bool make_not_used() { return make_not_entrant_helper(not_used); }
|
||||||
|
|
|
@ -202,7 +202,7 @@ public:
|
||||||
|
|
||||||
virtual address verified_entry_point() const = 0;
|
virtual address verified_entry_point() const = 0;
|
||||||
virtual void log_identity(xmlStream* log) const = 0;
|
virtual void log_identity(xmlStream* log) const = 0;
|
||||||
virtual void log_state_change() const = 0;
|
virtual void log_state_change(oop cause = NULL) const = 0;
|
||||||
virtual bool make_not_used() = 0;
|
virtual bool make_not_used() = 0;
|
||||||
virtual bool make_not_entrant() = 0;
|
virtual bool make_not_entrant() = 0;
|
||||||
virtual bool make_entrant() = 0;
|
virtual bool make_entrant() = 0;
|
||||||
|
|
|
@ -422,7 +422,7 @@ void nmethod::init_defaults() {
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
_jvmci_installed_code = NULL;
|
_jvmci_installed_code = NULL;
|
||||||
_speculation_log = NULL;
|
_speculation_log = NULL;
|
||||||
_jvmci_installed_code_triggers_unloading = false;
|
_jvmci_installed_code_triggers_invalidation = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,9 +690,9 @@ nmethod::nmethod(
|
||||||
_speculation_log = speculation_log;
|
_speculation_log = speculation_log;
|
||||||
oop obj = JNIHandles::resolve(installed_code);
|
oop obj = JNIHandles::resolve(installed_code);
|
||||||
if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) {
|
if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) {
|
||||||
_jvmci_installed_code_triggers_unloading = false;
|
_jvmci_installed_code_triggers_invalidation = false;
|
||||||
} else {
|
} else {
|
||||||
_jvmci_installed_code_triggers_unloading = true;
|
_jvmci_installed_code_triggers_invalidation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compiler->is_jvmci()) {
|
if (compiler->is_jvmci()) {
|
||||||
|
@ -786,6 +786,13 @@ void nmethod::log_identity(xmlStream* log) const {
|
||||||
if (TieredCompilation) {
|
if (TieredCompilation) {
|
||||||
log->print(" level='%d'", comp_level());
|
log->print(" level='%d'", comp_level());
|
||||||
}
|
}
|
||||||
|
#if INCLUDE_JVMCI
|
||||||
|
char buffer[O_BUFLEN];
|
||||||
|
char* jvmci_name = jvmci_installed_code_name(buffer, O_BUFLEN);
|
||||||
|
if (jvmci_name != NULL) {
|
||||||
|
log->print(" jvmci_installed_code_name='%s'", jvmci_name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1083,7 +1090,7 @@ void nmethod::make_unloaded(oop cause) {
|
||||||
_state = unloaded;
|
_state = unloaded;
|
||||||
|
|
||||||
// Log the unloading.
|
// Log the unloading.
|
||||||
log_state_change();
|
log_state_change(cause);
|
||||||
|
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
// The method can only be unloaded after the pointer to the installed code
|
// The method can only be unloaded after the pointer to the installed code
|
||||||
|
@ -1107,7 +1114,7 @@ void nmethod::invalidate_osr_method() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nmethod::log_state_change() const {
|
void nmethod::log_state_change(oop cause) const {
|
||||||
if (LogCompilation) {
|
if (LogCompilation) {
|
||||||
if (xtty != NULL) {
|
if (xtty != NULL) {
|
||||||
ttyLocker ttyl; // keep the following output all in one block
|
ttyLocker ttyl; // keep the following output all in one block
|
||||||
|
@ -1120,6 +1127,9 @@ void nmethod::log_state_change() const {
|
||||||
(_state == zombie ? " zombie='1'" : ""));
|
(_state == zombie ? " zombie='1'" : ""));
|
||||||
}
|
}
|
||||||
log_identity(xtty);
|
log_identity(xtty);
|
||||||
|
if (cause != NULL) {
|
||||||
|
xtty->print(" cause='%s'", cause->klass()->external_name());
|
||||||
|
}
|
||||||
xtty->stamp();
|
xtty->stamp();
|
||||||
xtty->end_elem();
|
xtty->end_elem();
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1160,8 @@ bool nmethod::make_not_entrant_or_zombie(int state) {
|
||||||
// Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
|
// Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
|
||||||
nmethodLocker nml(this);
|
nmethodLocker nml(this);
|
||||||
methodHandle the_method(method());
|
methodHandle the_method(method());
|
||||||
NoSafepointVerifier nsv;
|
// This can be called while the system is already at a safepoint which is ok
|
||||||
|
NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
|
||||||
|
|
||||||
// during patching, depending on the nmethod state we must notify the GC that
|
// during patching, depending on the nmethod state we must notify the GC that
|
||||||
// code has been unloaded, unregistering it. We cannot do this right while
|
// code has been unloaded, unregistering it. We cannot do this right while
|
||||||
|
@ -1507,13 +1518,12 @@ bool nmethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_aliv
|
||||||
bool nmethod::do_unloading_jvmci() {
|
bool nmethod::do_unloading_jvmci() {
|
||||||
if (_jvmci_installed_code != NULL) {
|
if (_jvmci_installed_code != NULL) {
|
||||||
if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
|
if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
|
||||||
if (_jvmci_installed_code_triggers_unloading) {
|
if (_jvmci_installed_code_triggers_invalidation) {
|
||||||
// jweak reference processing has already cleared the referent
|
// The reference to the installed code has been dropped so invalidate
|
||||||
make_unloaded(NULL);
|
// this nmethod and allow the sweeper to reclaim it.
|
||||||
return true;
|
make_not_entrant();
|
||||||
} else {
|
|
||||||
clear_jvmci_installed_code();
|
|
||||||
}
|
}
|
||||||
|
clear_jvmci_installed_code();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -2948,7 +2958,7 @@ oop nmethod::speculation_log() {
|
||||||
return JNIHandles::resolve(_speculation_log);
|
return JNIHandles::resolve(_speculation_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) {
|
char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) const {
|
||||||
if (!this->is_compiled_by_jvmci()) {
|
if (!this->is_compiled_by_jvmci()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ class nmethod : public CompiledMethod {
|
||||||
// That is, installed code other than a "default"
|
// That is, installed code other than a "default"
|
||||||
// HotSpotNMethod causes nmethod unloading.
|
// HotSpotNMethod causes nmethod unloading.
|
||||||
// This field is ignored once _jvmci_installed_code is NULL.
|
// This field is ignored once _jvmci_installed_code is NULL.
|
||||||
bool _jvmci_installed_code_triggers_unloading;
|
bool _jvmci_installed_code_triggers_invalidation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// To support simple linked-list chaining of nmethods:
|
// To support simple linked-list chaining of nmethods:
|
||||||
|
@ -456,7 +456,7 @@ public:
|
||||||
// Copies the value of the name field in the InstalledCode
|
// Copies the value of the name field in the InstalledCode
|
||||||
// object (if any) associated with this nmethod into buf.
|
// object (if any) associated with this nmethod into buf.
|
||||||
// Returns the value of buf if it was updated otherwise NULL.
|
// Returns the value of buf if it was updated otherwise NULL.
|
||||||
char* jvmci_installed_code_name(char* buf, size_t buflen);
|
char* jvmci_installed_code_name(char* buf, size_t buflen) const;
|
||||||
|
|
||||||
// Updates the state of the InstalledCode (if any) associated with
|
// Updates the state of the InstalledCode (if any) associated with
|
||||||
// this nmethod based on the current value of _state.
|
// this nmethod based on the current value of _state.
|
||||||
|
@ -486,7 +486,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive);
|
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive);
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
// See comment for _jvmci_installed_code_triggers_unloading field.
|
// See comment for _jvmci_installed_code_triggers_invalidation field.
|
||||||
// Returns whether this nmethod was unloaded.
|
// Returns whether this nmethod was unloaded.
|
||||||
virtual bool do_unloading_jvmci();
|
virtual bool do_unloading_jvmci();
|
||||||
#endif
|
#endif
|
||||||
|
@ -555,7 +555,7 @@ public:
|
||||||
// Logging
|
// Logging
|
||||||
void log_identity(xmlStream* log) const;
|
void log_identity(xmlStream* log) const;
|
||||||
void log_new_nmethod() const;
|
void log_new_nmethod() const;
|
||||||
void log_state_change() const;
|
void log_state_change(oop cause = NULL) const;
|
||||||
|
|
||||||
// Prints block-level comments, including nmethod specific block labels:
|
// Prints block-level comments, including nmethod specific block labels:
|
||||||
virtual void print_block_comment(outputStream* stream, address block_begin) const {
|
virtual void print_block_comment(outputStream* stream, address block_begin) const {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue