< 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 >