mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8192003: Refactor weak references in StringTable to use the Access API
Reviewed-by: pliden, dholmes, coleenp
This commit is contained in:
parent
add0d817f5
commit
c54ef2b296
7 changed files with 72 additions and 55 deletions
|
@ -35,6 +35,7 @@
|
|||
#include "memory/filemap.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
|
@ -43,7 +44,6 @@
|
|||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc/g1/g1CollectedHeap.hpp"
|
||||
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
|
||||
#include "gc/g1/g1StringDedup.hpp"
|
||||
#endif
|
||||
|
||||
|
@ -124,6 +124,22 @@ unsigned int StringTable::hash_string(oop string) {
|
|||
}
|
||||
}
|
||||
|
||||
oop StringTable::string_object(HashtableEntry<oop, mtSymbol>* entry) {
|
||||
return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(entry->literal_addr());
|
||||
}
|
||||
|
||||
oop StringTable::string_object_no_keepalive(HashtableEntry<oop, mtSymbol>* entry) {
|
||||
// The AS_NO_KEEPALIVE peeks at the oop without keeping it alive.
|
||||
// This is *very dangerous* in general but is okay in this specific
|
||||
// case. The subsequent oop_load keeps the oop alive if it it matched
|
||||
// the jchar* string.
|
||||
return RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(entry->literal_addr());
|
||||
}
|
||||
|
||||
void StringTable::set_string_object(HashtableEntry<oop, mtSymbol>* entry, oop string) {
|
||||
RootAccess<ON_PHANTOM_OOP_REF>::oop_store(entry->literal_addr(), string);
|
||||
}
|
||||
|
||||
oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
|
||||
assert(hash == java_lang_String::hash_code(name, len),
|
||||
"hash must be computed using java_lang_String::hash_code");
|
||||
|
@ -131,13 +147,16 @@ oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
|
|||
}
|
||||
|
||||
oop StringTable::lookup_in_main_table(int index, jchar* name,
|
||||
int len, unsigned int hash) {
|
||||
int len, unsigned int hash) {
|
||||
int count = 0;
|
||||
for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
|
||||
count++;
|
||||
if (l->hash() == hash) {
|
||||
if (java_lang_String::equals(l->literal(), name, len)) {
|
||||
return l->literal();
|
||||
if (java_lang_String::equals(string_object_no_keepalive(l), name, len)) {
|
||||
// We must perform a new load with string_object() that keeps the string
|
||||
// alive as we must expose the oop as strongly reachable when exiting
|
||||
// this context, in case the oop gets published.
|
||||
return string_object(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -192,18 +211,6 @@ oop StringTable::lookup(Symbol* symbol) {
|
|||
return lookup(chars, length);
|
||||
}
|
||||
|
||||
// Tell the GC that this string was looked up in the StringTable.
|
||||
static void ensure_string_alive(oop string) {
|
||||
// A lookup in the StringTable 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 && string != NULL) {
|
||||
G1SATBCardTableModRefBS::enqueue(string);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
oop StringTable::lookup(jchar* name, int len) {
|
||||
// shared table always uses java_lang_String::hash_code
|
||||
unsigned int hash = java_lang_String::hash_code(name, len);
|
||||
|
@ -217,8 +224,6 @@ oop StringTable::lookup(jchar* name, int len) {
|
|||
int index = the_table()->hash_to_index(hash);
|
||||
string = the_table()->lookup_in_main_table(index, name, len, hash);
|
||||
|
||||
ensure_string_alive(string);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
@ -238,9 +243,6 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
|
|||
|
||||
// Found
|
||||
if (found_string != NULL) {
|
||||
if (found_string != string_or_null()) {
|
||||
ensure_string_alive(found_string);
|
||||
}
|
||||
return found_string;
|
||||
}
|
||||
|
||||
|
@ -276,10 +278,6 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
|
|||
hashValue, CHECK_NULL);
|
||||
}
|
||||
|
||||
if (added_or_found != string()) {
|
||||
ensure_string_alive(added_or_found);
|
||||
}
|
||||
|
||||
return added_or_found;
|
||||
}
|
||||
|
||||
|
@ -388,9 +386,9 @@ void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClos
|
|||
while (entry != NULL) {
|
||||
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||
|
||||
if (is_alive->do_object_b(entry->literal())) {
|
||||
if (is_alive->do_object_b(string_object_no_keepalive(entry))) {
|
||||
if (f != NULL) {
|
||||
f->do_oop((oop*)entry->literal_addr());
|
||||
f->do_oop(entry->literal_addr());
|
||||
}
|
||||
p = entry->next_addr();
|
||||
} else {
|
||||
|
@ -429,7 +427,7 @@ void StringTable::verify() {
|
|||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
|
||||
for ( ; p != NULL; p = p->next()) {
|
||||
oop s = p->literal();
|
||||
oop s = string_object_no_keepalive(p);
|
||||
guarantee(s != NULL, "interned string is NULL");
|
||||
unsigned int h = hash_string(s);
|
||||
guarantee(p->hash() == h, "broken hash in string table entry");
|
||||
|
@ -448,10 +446,10 @@ void StringTable::dump(outputStream* st, bool verbose) {
|
|||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
|
||||
for ( ; p != NULL; p = p->next()) {
|
||||
oop s = p->literal();
|
||||
typeArrayOop value = java_lang_String::value(s);
|
||||
int length = java_lang_String::length(s);
|
||||
bool is_latin1 = java_lang_String::is_latin1(s);
|
||||
oop s = string_object_no_keepalive(p);
|
||||
typeArrayOop value = java_lang_String::value_no_keepalive(s);
|
||||
int length = java_lang_String::length(s);
|
||||
bool is_latin1 = java_lang_String::is_latin1(s);
|
||||
|
||||
if (length <= 0) {
|
||||
st->print("%d: ", length);
|
||||
|
@ -484,8 +482,8 @@ StringTable::VerifyRetTypes StringTable::compare_entries(
|
|||
HashtableEntry<oop, mtSymbol>* e_ptr2) {
|
||||
// These entries are sanity checked by verify_and_compare_entries()
|
||||
// before this function is called.
|
||||
oop str1 = e_ptr1->literal();
|
||||
oop str2 = e_ptr2->literal();
|
||||
oop str1 = string_object_no_keepalive(e_ptr1);
|
||||
oop str2 = string_object_no_keepalive(e_ptr2);
|
||||
|
||||
if (str1 == str2) {
|
||||
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
|
||||
|
@ -505,12 +503,12 @@ StringTable::VerifyRetTypes StringTable::compare_entries(
|
|||
}
|
||||
|
||||
StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
StringTable::VerifyMesgModes mesg_mode) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
StringTable::VerifyMesgModes mesg_mode) {
|
||||
|
||||
VerifyRetTypes ret = _verify_pass; // be optimistic
|
||||
|
||||
oop str = e_ptr->literal();
|
||||
oop str = string_object_no_keepalive(e_ptr);
|
||||
if (str == NULL) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,
|
||||
|
@ -684,7 +682,7 @@ oop StringTable::create_archived_string(oop s, Thread* THREAD) {
|
|||
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
|
||||
|
||||
oop new_s = NULL;
|
||||
typeArrayOop v = java_lang_String::value(s);
|
||||
typeArrayOop v = java_lang_String::value_no_keepalive(s);
|
||||
typeArrayOop new_v = (typeArrayOop)MetaspaceShared::archive_heap_object(v, THREAD);
|
||||
if (new_v == NULL) {
|
||||
return NULL;
|
||||
|
@ -708,7 +706,7 @@ bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
|
|||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* bucket = the_table()->bucket(i);
|
||||
for ( ; bucket != NULL; bucket = bucket->next()) {
|
||||
oop s = bucket->literal();
|
||||
oop s = string_object_no_keepalive(bucket);
|
||||
unsigned int hash = java_lang_String::hash_code(s);
|
||||
if (hash == 0) {
|
||||
continue;
|
||||
|
@ -721,7 +719,7 @@ bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
|
|||
}
|
||||
|
||||
// set the archived string in bucket
|
||||
bucket->set_literal(new_s);
|
||||
set_string_object(bucket, new_s);
|
||||
|
||||
// add to the compact table
|
||||
writer->add(hash, new_s);
|
||||
|
@ -763,4 +761,3 @@ void StringTable::shared_oops_do(OopClosure* f) {
|
|||
_shared_table.oops_do(f);
|
||||
}
|
||||
#endif //INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue