< prev index next >
src/hotspot/share/classfile/stringTable.cpp
Print this page
rev 48017 : [mq]: Access_strings
@@ -33,19 +33,19 @@
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#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"
#include "services/diagnosticCommand.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1CollectedHeap.hpp"
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/g1StringDedup.hpp"
#endif
// the number of buckets a thread claims
const int ClaimChunkSize = 32;
@@ -122,10 +122,26 @@
vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
return 0;
}
}
+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");
return _shared_table.lookup((const char*)name, hash, len);
}
@@ -134,12 +150,13 @@
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();
+ oop string = string_object_no_keepalive(l);
+ if (java_lang_String::equals(string, name, len)) {
+ return string_object(l);
}
}
}
// If the bucket size is too deep check if this hash code is insufficient.
if (count >= rehash_count && !needs_rehashing()) {
@@ -190,22 +207,10 @@
int length;
jchar* chars = symbol->as_unicode(length);
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);
oop string = lookup_shared(name, len, hash);
if (string != NULL) {
@@ -215,12 +220,10 @@
hash = alt_hash_string(name, 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;
}
oop StringTable::intern(Handle string_or_null, jchar* name,
int len, TRAPS) {
@@ -236,13 +239,10 @@
int index = the_table()->hash_to_index(hashValue);
found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
// Found
if (found_string != NULL) {
- if (found_string != string_or_null()) {
- ensure_string_alive(found_string);
- }
return found_string;
}
debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
assert(!Universe::heap()->is_in_reserved(name),
@@ -274,14 +274,10 @@
// Otherwise, add to symbol to table
added_or_found = the_table()->basic_add(index, string, name, len,
hashValue, CHECK_NULL);
}
- if (added_or_found != string()) {
- ensure_string_alive(added_or_found);
- }
-
return added_or_found;
}
oop StringTable::intern(Symbol* symbol, TRAPS) {
if (symbol == NULL) return NULL;
@@ -386,13 +382,13 @@
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
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 {
*p = entry->next();
context->free_entry(entry);
@@ -427,11 +423,11 @@
// See StringTable::verify_and_compare() below for exhaustive verification.
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");
guarantee(the_table()->hash_to_index(h) == i,
"wrong index in string table");
@@ -446,12 +442,12 @@
Thread* THREAD = Thread::current();
st->print_cr("VERSION: 1.1");
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);
+ 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);
@@ -482,12 +478,12 @@
HashtableEntry<oop, mtSymbol>* e_ptr1,
int bkt2, int e_cnt2,
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 ") "
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
p2i(str1), bkt1, e_cnt1, bkt2, e_cnt2);
@@ -508,11 +504,11 @@
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,
e_cnt);
}
@@ -682,11 +678,11 @@
// Sharing
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;
}
new_s = MetaspaceShared::archive_heap_object(s, THREAD);
@@ -706,11 +702,11 @@
Thread* THREAD = Thread::current();
G1CollectedHeap::heap()->begin_archive_alloc_range();
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;
}
@@ -719,11 +715,11 @@
if (new_s == NULL) {
continue;
}
// 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);
}
}
@@ -761,6 +757,5 @@
void StringTable::shared_oops_do(OopClosure* f) {
_shared_table.oops_do(f);
}
#endif //INCLUDE_CDS_JAVA_HEAP
-
< prev index next >