< prev index next >
src/share/vm/gc/g1/g1StringDedupTable.cpp
Print this page
*** 196,209 ****
assert(_table == NULL, "One string deduplication table allowed");
_entry_cache = new G1StringDedupEntryCache();
_table = new G1StringDedupTable(_min_size);
}
! void G1StringDedupTable::add(typeArrayOop value, unsigned int hash, G1StringDedupEntry** list) {
G1StringDedupEntry* entry = _entry_cache->alloc();
entry->set_obj(value);
entry->set_hash(hash);
entry->set_next(*list);
*list = entry;
_entries++;
}
--- 196,210 ----
assert(_table == NULL, "One string deduplication table allowed");
_entry_cache = new G1StringDedupEntryCache();
_table = new G1StringDedupTable(_min_size);
}
! void G1StringDedupTable::add(typeArrayOop value, bool latin1, unsigned int hash, G1StringDedupEntry** list) {
G1StringDedupEntry* entry = _entry_cache->alloc();
entry->set_obj(value);
entry->set_hash(hash);
+ entry->set_latin1(latin1);
entry->set_next(*list);
*list = entry;
_entries++;
}
*** 224,242 ****
}
bool G1StringDedupTable::equals(typeArrayOop value1, typeArrayOop value2) {
return (value1 == value2 ||
(value1->length() == value2->length() &&
! (!memcmp(value1->base(T_CHAR),
! value2->base(T_CHAR),
! value1->length() * sizeof(jchar)))));
}
! typeArrayOop G1StringDedupTable::lookup(typeArrayOop value, unsigned int hash,
G1StringDedupEntry** list, uintx &count) {
for (G1StringDedupEntry* entry = *list; entry != NULL; entry = entry->next()) {
! if (entry->hash() == hash) {
typeArrayOop existing_value = entry->obj();
if (equals(value, existing_value)) {
// Match found
return existing_value;
}
--- 225,243 ----
}
bool G1StringDedupTable::equals(typeArrayOop value1, typeArrayOop value2) {
return (value1 == value2 ||
(value1->length() == value2->length() &&
! (!memcmp(value1->base(T_BYTE),
! value2->base(T_BYTE),
! value1->length() * sizeof(jbyte)))));
}
! typeArrayOop G1StringDedupTable::lookup(typeArrayOop value, bool latin1, unsigned int hash,
G1StringDedupEntry** list, uintx &count) {
for (G1StringDedupEntry* entry = *list; entry != NULL; entry = entry->next()) {
! if (entry->hash() == hash && entry->latin1() == latin1) {
typeArrayOop existing_value = entry->obj();
if (equals(value, existing_value)) {
// Match found
return existing_value;
}
*** 246,289 ****
// Not found
return NULL;
}
! typeArrayOop G1StringDedupTable::lookup_or_add_inner(typeArrayOop value, unsigned int hash) {
size_t index = hash_to_index(hash);
G1StringDedupEntry** list = bucket(index);
uintx count = 0;
// Lookup in list
! typeArrayOop existing_value = lookup(value, hash, list, count);
// Check if rehash is needed
if (count > _rehash_threshold) {
_rehash_needed = true;
}
if (existing_value == NULL) {
// Not found, add new entry
! add(value, hash, list);
// Update statistics
_entries_added++;
}
return existing_value;
}
! unsigned int G1StringDedupTable::hash_code(typeArrayOop value) {
unsigned int hash;
int length = value->length();
const jchar* data = (jchar*)value->base(T_CHAR);
-
if (use_java_hash()) {
hash = java_lang_String::hash_code(data, length);
} else {
hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
}
return hash;
}
void G1StringDedupTable::deduplicate(oop java_string, G1StringDedupStat& stat) {
--- 247,299 ----
// Not found
return NULL;
}
! typeArrayOop G1StringDedupTable::lookup_or_add_inner(typeArrayOop value, bool latin1, unsigned int hash) {
size_t index = hash_to_index(hash);
G1StringDedupEntry** list = bucket(index);
uintx count = 0;
// Lookup in list
! typeArrayOop existing_value = lookup(value, latin1, hash, list, count);
// Check if rehash is needed
if (count > _rehash_threshold) {
_rehash_needed = true;
}
if (existing_value == NULL) {
// Not found, add new entry
! add(value, latin1, hash, list);
// Update statistics
_entries_added++;
}
return existing_value;
}
! unsigned int G1StringDedupTable::hash_code(typeArrayOop value, bool latin1) {
unsigned int hash;
int length = value->length();
+ if (latin1) {
+ const jbyte* data = (jbyte*)value->base(T_BYTE);
+ if (use_java_hash()) {
+ hash = java_lang_String::hash_code(data, length);
+ } else {
+ hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
+ }
+ } else {
+ length /= sizeof(jchar) / sizeof(jbyte); // Convert number of bytes to number of chars
const jchar* data = (jchar*)value->base(T_CHAR);
if (use_java_hash()) {
hash = java_lang_String::hash_code(data, length);
} else {
hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
}
+ }
return hash;
}
void G1StringDedupTable::deduplicate(oop java_string, G1StringDedupStat& stat) {
*** 297,325 ****
// String has no value
stat.inc_skipped();
return;
}
unsigned int hash = 0;
if (use_java_hash()) {
// Get hash code from cache
hash = java_lang_String::hash(java_string);
}
if (hash == 0) {
// Compute hash
! hash = hash_code(value);
stat.inc_hashed();
if (use_java_hash() && hash != 0) {
// Store hash code in cache
java_lang_String::set_hash(java_string, hash);
}
}
! typeArrayOop existing_value = lookup_or_add(value, hash);
if (existing_value == value) {
// Same value, already known
stat.inc_known();
return;
}
--- 307,336 ----
// String has no value
stat.inc_skipped();
return;
}
+ bool latin1 = java_lang_String::is_latin1(java_string);
unsigned int hash = 0;
if (use_java_hash()) {
// Get hash code from cache
hash = java_lang_String::hash(java_string);
}
if (hash == 0) {
// Compute hash
! hash = hash_code(value, latin1);
stat.inc_hashed();
if (use_java_hash() && hash != 0) {
// Store hash code in cache
java_lang_String::set_hash(java_string, hash);
}
}
! typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
if (existing_value == value) {
// Same value, already known
stat.inc_known();
return;
}
*** 457,467 ****
// in the table. We can't transfer entries into the new table
// at this point since we don't have exclusive access to all
// destination partitions. finish_rehash() will do a single
// threaded transfer of all entries.
typeArrayOop value = (typeArrayOop)*p;
! unsigned int hash = hash_code(value);
(*entry)->set_hash(hash);
}
// Move to next entry
entry = (*entry)->next_addr();
--- 468,479 ----
// in the table. We can't transfer entries into the new table
// at this point since we don't have exclusive access to all
// destination partitions. finish_rehash() will do a single
// threaded transfer of all entries.
typeArrayOop value = (typeArrayOop)*p;
! bool latin1 = (*entry)->latin1();
! unsigned int hash = hash_code(value, latin1);
(*entry)->set_hash(hash);
}
// Move to next entry
entry = (*entry)->next_addr();
*** 521,531 ****
typeArrayOop value = (*entry)->obj();
guarantee(value != NULL, "Object must not be NULL");
guarantee(G1CollectedHeap::heap()->is_in_reserved(value), "Object must be on the heap");
guarantee(!value->is_forwarded(), "Object must not be forwarded");
guarantee(value->is_typeArray(), "Object must be a typeArrayOop");
! unsigned int hash = hash_code(value);
guarantee((*entry)->hash() == hash, "Table entry has inorrect hash");
guarantee(_table->hash_to_index(hash) == bucket, "Table entry has incorrect index");
entry = (*entry)->next_addr();
}
--- 533,544 ----
typeArrayOop value = (*entry)->obj();
guarantee(value != NULL, "Object must not be NULL");
guarantee(G1CollectedHeap::heap()->is_in_reserved(value), "Object must be on the heap");
guarantee(!value->is_forwarded(), "Object must not be forwarded");
guarantee(value->is_typeArray(), "Object must be a typeArrayOop");
! bool latin1 = (*entry)->latin1();
! unsigned int hash = hash_code(value, latin1);
guarantee((*entry)->hash() == hash, "Table entry has inorrect hash");
guarantee(_table->hash_to_index(hash) == bucket, "Table entry has incorrect index");
entry = (*entry)->next_addr();
}
*** 534,547 ****
// identical array has been inserted more than once into different/incorrect
// buckets the verification step above will catch that.
G1StringDedupEntry** entry1 = _table->bucket(bucket);
while (*entry1 != NULL) {
typeArrayOop value1 = (*entry1)->obj();
G1StringDedupEntry** entry2 = (*entry1)->next_addr();
while (*entry2 != NULL) {
typeArrayOop value2 = (*entry2)->obj();
! guarantee(!equals(value1, value2), "Table entries must not have identical arrays");
entry2 = (*entry2)->next_addr();
}
entry1 = (*entry1)->next_addr();
}
}
--- 547,562 ----
// identical array has been inserted more than once into different/incorrect
// buckets the verification step above will catch that.
G1StringDedupEntry** entry1 = _table->bucket(bucket);
while (*entry1 != NULL) {
typeArrayOop value1 = (*entry1)->obj();
+ bool latin1_1 = (*entry1)->latin1();
G1StringDedupEntry** entry2 = (*entry1)->next_addr();
while (*entry2 != NULL) {
typeArrayOop value2 = (*entry2)->obj();
! bool latin1_2 = (*entry2)->latin1();
! guarantee(latin1_1 != latin1_2 || !equals(value1, value2), "Table entries must not have identical arrays");
entry2 = (*entry2)->next_addr();
}
entry1 = (*entry1)->next_addr();
}
}
< prev index next >