8191904: Refactor weak oops in ResolvedMethodTable to use the Access API
Reviewed-by: kbarrett, coleenp
This commit is contained in:
parent
8f739404a7
commit
c6bbed9592
@ -25,6 +25,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "gc/shared/gcLocker.hpp"
|
#include "gc/shared/gcLocker.hpp"
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
|
#include "oops/access.inline.hpp"
|
||||||
#include "oops/oop.inline.hpp"
|
#include "oops/oop.inline.hpp"
|
||||||
#include "oops/method.hpp"
|
#include "oops/method.hpp"
|
||||||
#include "oops/symbol.hpp"
|
#include "oops/symbol.hpp"
|
||||||
@ -33,24 +34,39 @@
|
|||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "utilities/hashtable.inline.hpp"
|
#include "utilities/hashtable.inline.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
#if INCLUDE_ALL_GCS
|
|
||||||
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
oop ResolvedMethodEntry::object() {
|
||||||
|
return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(literal_addr());
|
||||||
|
}
|
||||||
|
|
||||||
|
oop ResolvedMethodEntry::object_no_keepalive() {
|
||||||
|
// The AS_NO_KEEPALIVE peeks at the oop without keeping it alive.
|
||||||
|
// This is dangerous in general but is okay if the loaded oop does
|
||||||
|
// not leak out past a thread transition where a safepoint can happen.
|
||||||
|
// A subsequent oop_load without AS_NO_KEEPALIVE (the object() accessor)
|
||||||
|
// keeps the oop alive before doing so.
|
||||||
|
return RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(literal_addr());
|
||||||
|
}
|
||||||
|
|
||||||
ResolvedMethodTable::ResolvedMethodTable()
|
ResolvedMethodTable::ResolvedMethodTable()
|
||||||
: Hashtable<oop, mtClass>(_table_size, sizeof(ResolvedMethodEntry)) { }
|
: Hashtable<oop, mtClass>(_table_size, sizeof(ResolvedMethodEntry)) { }
|
||||||
|
|
||||||
oop ResolvedMethodTable::lookup(int index, unsigned int hash, Method* method) {
|
oop ResolvedMethodTable::lookup(int index, unsigned int hash, Method* method) {
|
||||||
for (ResolvedMethodEntry* p = bucket(index); p != NULL; p = p->next()) {
|
for (ResolvedMethodEntry* p = bucket(index); p != NULL; p = p->next()) {
|
||||||
if (p->hash() == hash) {
|
if (p->hash() == hash) {
|
||||||
oop target = p->literal();
|
|
||||||
|
// Peek the object to check if it is the right target.
|
||||||
|
oop target = p->object_no_keepalive();
|
||||||
|
|
||||||
// The method is in the table as a target already
|
// The method is in the table as a target already
|
||||||
if (java_lang_invoke_ResolvedMethodName::vmtarget(target) == method) {
|
if (java_lang_invoke_ResolvedMethodName::vmtarget(target) == method) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
log_debug(membername, table) ("ResolvedMethod entry found for %s index %d",
|
log_debug(membername, table) ("ResolvedMethod entry found for %s index %d",
|
||||||
method->name_and_sig_as_C_string(), index);
|
method->name_and_sig_as_C_string(), index);
|
||||||
return target;
|
// The object() accessor makes sure the target object is kept alive before
|
||||||
|
// leaking out.
|
||||||
|
return p->object();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,18 +86,6 @@ oop ResolvedMethodTable::lookup(Method* method) {
|
|||||||
return lookup(index, hash, method);
|
return lookup(index, hash, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the GC that this oop was looked up in the table
|
|
||||||
static void ensure_oop_alive(oop mname) {
|
|
||||||
// A lookup in the ResolvedMethodTable could return an object that was previously
|
|
||||||
// considered dead. The SATB part of G1 needs to get notified about this
|
|
||||||
// potential resurrection, otherwise the marking might not find the object.
|
|
||||||
#if INCLUDE_ALL_GCS
|
|
||||||
if (UseG1GC && mname != NULL) {
|
|
||||||
G1SATBCardTableModRefBS::enqueue(mname);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
oop ResolvedMethodTable::basic_add(Method* method, oop rmethod_name) {
|
oop ResolvedMethodTable::basic_add(Method* method, oop rmethod_name) {
|
||||||
assert_locked_or_safepoint(ResolvedMethodTable_lock);
|
assert_locked_or_safepoint(ResolvedMethodTable_lock);
|
||||||
|
|
||||||
@ -91,7 +95,6 @@ oop ResolvedMethodTable::basic_add(Method* method, oop rmethod_name) {
|
|||||||
// One was added while aquiring the lock
|
// One was added while aquiring the lock
|
||||||
oop entry = lookup(index, hash, method);
|
oop entry = lookup(index, hash, method);
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
ensure_oop_alive(entry);
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,14 +103,13 @@ oop ResolvedMethodTable::basic_add(Method* method, oop rmethod_name) {
|
|||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
log_debug(membername, table) ("ResolvedMethod entry added for %s index %d",
|
log_debug(membername, table) ("ResolvedMethod entry added for %s index %d",
|
||||||
method->name_and_sig_as_C_string(), index);
|
method->name_and_sig_as_C_string(), index);
|
||||||
return p->literal();
|
return rmethod_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolvedMethodTable* ResolvedMethodTable::_the_table = NULL;
|
ResolvedMethodTable* ResolvedMethodTable::_the_table = NULL;
|
||||||
|
|
||||||
oop ResolvedMethodTable::find_method(Method* method) {
|
oop ResolvedMethodTable::find_method(Method* method) {
|
||||||
oop entry = _the_table->lookup(method);
|
oop entry = _the_table->lookup(method);
|
||||||
ensure_oop_alive(entry);
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,12 +149,12 @@ void ResolvedMethodTable::unlink(BoolObjectClosure* is_alive) {
|
|||||||
ResolvedMethodEntry* entry = _the_table->bucket(i);
|
ResolvedMethodEntry* entry = _the_table->bucket(i);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
_oops_counted++;
|
_oops_counted++;
|
||||||
if (is_alive->do_object_b(entry->literal())) {
|
if (is_alive->do_object_b(entry->object_no_keepalive())) {
|
||||||
p = entry->next_addr();
|
p = entry->next_addr();
|
||||||
} else {
|
} else {
|
||||||
_oops_removed++;
|
_oops_removed++;
|
||||||
if (log_is_enabled(Debug, membername, table)) {
|
if (log_is_enabled(Debug, membername, table)) {
|
||||||
Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(entry->literal());
|
Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(entry->object_no_keepalive());
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
log_debug(membername, table) ("ResolvedMethod entry removed for %s index %d",
|
log_debug(membername, table) ("ResolvedMethod entry removed for %s index %d",
|
||||||
m->name_and_sig_as_C_string(), i);
|
m->name_and_sig_as_C_string(), i);
|
||||||
@ -185,7 +187,7 @@ void ResolvedMethodTable::print() {
|
|||||||
ResolvedMethodEntry* entry = bucket(i);
|
ResolvedMethodEntry* entry = bucket(i);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
tty->print("%d : ", i);
|
tty->print("%d : ", i);
|
||||||
oop rmethod_name = entry->literal();
|
oop rmethod_name = entry->object_no_keepalive();
|
||||||
rmethod_name->print();
|
rmethod_name->print();
|
||||||
Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name);
|
Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name);
|
||||||
m->print();
|
m->print();
|
||||||
@ -203,8 +205,7 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
|||||||
for (int i = 0; i < _the_table->table_size(); ++i) {
|
for (int i = 0; i < _the_table->table_size(); ++i) {
|
||||||
ResolvedMethodEntry* entry = _the_table->bucket(i);
|
ResolvedMethodEntry* entry = _the_table->bucket(i);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
|
oop mem_name = entry->object_no_keepalive();
|
||||||
oop mem_name = entry->literal();
|
|
||||||
Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
||||||
|
|
||||||
if (old_method->is_old()) {
|
if (old_method->is_old()) {
|
||||||
|
@ -44,6 +44,9 @@ class ResolvedMethodEntry : public HashtableEntry<oop, mtClass> {
|
|||||||
return (ResolvedMethodEntry**)HashtableEntry<oop, mtClass>::next_addr();
|
return (ResolvedMethodEntry**)HashtableEntry<oop, mtClass>::next_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oop object();
|
||||||
|
oop object_no_keepalive();
|
||||||
|
|
||||||
void print_on(outputStream* st) const;
|
void print_on(outputStream* st) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user