< prev index next >

src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp

Print this page


   1 /*
   2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/altHashing.hpp"
  27 #include "classfile/javaClasses.inline.hpp"
  28 #include "gc/shared/stringdedup/stringDedup.hpp"
  29 #include "gc/shared/stringdedup/stringDedupTable.hpp"
  30 #include "gc/shared/suspendibleThreadSet.hpp"
  31 #include "logging/log.hpp"
  32 #include "memory/padded.inline.hpp"
  33 #include "memory/universe.hpp"
  34 #include "oops/access.inline.hpp"
  35 #include "oops/arrayOop.inline.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "oops/typeArrayOop.hpp"
  38 #include "runtime/mutexLocker.hpp"
  39 #include "runtime/safepointVerifiers.hpp"
  40 
  41 //
  42 // List of deduplication table entries. Links table
  43 // entries together using their _next fields.
  44 //
  45 class StringDedupEntryList : public CHeapObj<mtGC> {
  46 private:
  47   StringDedupEntry*   _list;
  48   size_t              _length;
  49 
  50 public:
  51   StringDedupEntryList() :
  52     _list(NULL),
  53     _length(0) {


 335   return hash;
 336 }
 337 
 338 void StringDedupTable::deduplicate(oop java_string, StringDedupStat* stat) {
 339   assert(java_lang_String::is_instance(java_string), "Must be a string");
 340   NoSafepointVerifier nsv;
 341 
 342   stat->inc_inspected();
 343 
 344   typeArrayOop value = java_lang_String::value(java_string);
 345   if (value == NULL) {
 346     // String has no value
 347     stat->inc_skipped();
 348     return;
 349   }
 350 
 351   bool latin1 = java_lang_String::is_latin1(java_string);
 352   unsigned int hash = 0;
 353 
 354   if (use_java_hash()) {
 355     if (!java_lang_String::hash_is_set(java_string)) {
 356       stat->inc_hashed();
 357     }
 358     hash = java_lang_String::hash_code(java_string);
 359   } else {
 360     // Compute hash
 361     hash = hash_code(value, latin1);
 362     stat->inc_hashed();





 363   }
 364 
 365   typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
 366   if (oopDesc::equals_raw(existing_value, value)) {
 367     // Same value, already known
 368     stat->inc_known();
 369     return;
 370   }
 371 
 372   // Get size of value array
 373   uintx size_in_bytes = value->size() * HeapWordSize;
 374   stat->inc_new(size_in_bytes);
 375 
 376   if (existing_value != NULL) {
 377     // Existing value found, deduplicate string
 378     java_lang_String::set_value(java_string, existing_value);
 379     stat->deduped(value, size_in_bytes);
 380   }
 381 }
 382 


 461 
 462   // Number of entries removed during the scan
 463   uintx removed = 0;
 464 
 465   for (;;) {
 466     // Grab next partition to scan
 467     size_t partition_begin = claim_table_partition(partition_size);
 468     size_t partition_end = partition_begin + partition_size;
 469     if (partition_begin >= table_half) {
 470       // End of table
 471       break;
 472     }
 473 
 474     // Scan the partition followed by the sibling partition in the second half of the table
 475     removed += unlink_or_oops_do(cl, partition_begin, partition_end, worker_id);
 476     removed += unlink_or_oops_do(cl, table_half + partition_begin, table_half + partition_end, worker_id);
 477   }
 478 
 479   // Delayed update to avoid contention on the table lock
 480   if (removed > 0) {
 481     MutexLocker ml(StringDedupTable_lock, Mutex::_no_safepoint_check_flag);
 482     _table->_entries -= removed;
 483     _entries_removed += removed;
 484   }
 485 }
 486 
 487 uintx StringDedupTable::unlink_or_oops_do(StringDedupUnlinkOrOopsDoClosure* cl,
 488                                           size_t partition_begin,
 489                                           size_t partition_end,
 490                                           uint worker_id) {
 491   uintx removed = 0;
 492   for (size_t bucket = partition_begin; bucket < partition_end; bucket++) {
 493     StringDedupEntry** entry = _table->bucket(bucket);
 494     while (*entry != NULL) {
 495       oop* p = (oop*)(*entry)->obj_addr();
 496       if (cl->is_alive(*p)) {
 497         cl->keep_alive(p);
 498         if (is_resizing()) {
 499           // We are resizing the table, transfer entry to the new table
 500           _table->transfer(entry, _resized_table);
 501         } else {


   1 /*
   2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/altHashing.hpp"
  27 #include "classfile/javaClasses.inline.hpp"
  28 #include "gc/shared/stringdedup/stringDedup.hpp"
  29 #include "gc/shared/stringdedup/stringDedupTable.hpp"
  30 #include "gc/shared/suspendibleThreadSet.hpp"
  31 #include "logging/log.hpp"
  32 #include "memory/padded.inline.hpp"

  33 #include "oops/access.inline.hpp"
  34 #include "oops/arrayOop.inline.hpp"
  35 #include "oops/oop.inline.hpp"
  36 #include "oops/typeArrayOop.hpp"
  37 #include "runtime/mutexLocker.hpp"
  38 #include "runtime/safepointVerifiers.hpp"
  39 
  40 //
  41 // List of deduplication table entries. Links table
  42 // entries together using their _next fields.
  43 //
  44 class StringDedupEntryList : public CHeapObj<mtGC> {
  45 private:
  46   StringDedupEntry*   _list;
  47   size_t              _length;
  48 
  49 public:
  50   StringDedupEntryList() :
  51     _list(NULL),
  52     _length(0) {


 334   return hash;
 335 }
 336 
 337 void StringDedupTable::deduplicate(oop java_string, StringDedupStat* stat) {
 338   assert(java_lang_String::is_instance(java_string), "Must be a string");
 339   NoSafepointVerifier nsv;
 340 
 341   stat->inc_inspected();
 342 
 343   typeArrayOop value = java_lang_String::value(java_string);
 344   if (value == NULL) {
 345     // String has no value
 346     stat->inc_skipped();
 347     return;
 348   }
 349 
 350   bool latin1 = java_lang_String::is_latin1(java_string);
 351   unsigned int hash = 0;
 352 
 353   if (use_java_hash()) {
 354     // Get hash code from cache
 355     hash = java_lang_String::hash(java_string);
 356   }
 357 
 358   if (hash == 0) {
 359     // Compute hash
 360     hash = hash_code(value, latin1);
 361     stat->inc_hashed();
 362 
 363     if (use_java_hash() && hash != 0) {
 364       // Store hash code in cache
 365       java_lang_String::set_hash(java_string, hash);
 366     }
 367   }
 368 
 369   typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
 370   if (oopDesc::equals_raw(existing_value, value)) {
 371     // Same value, already known
 372     stat->inc_known();
 373     return;
 374   }
 375 
 376   // Get size of value array
 377   uintx size_in_bytes = value->size() * HeapWordSize;
 378   stat->inc_new(size_in_bytes);
 379 
 380   if (existing_value != NULL) {
 381     // Existing value found, deduplicate string
 382     java_lang_String::set_value(java_string, existing_value);
 383     stat->deduped(value, size_in_bytes);
 384   }
 385 }
 386 


 465 
 466   // Number of entries removed during the scan
 467   uintx removed = 0;
 468 
 469   for (;;) {
 470     // Grab next partition to scan
 471     size_t partition_begin = claim_table_partition(partition_size);
 472     size_t partition_end = partition_begin + partition_size;
 473     if (partition_begin >= table_half) {
 474       // End of table
 475       break;
 476     }
 477 
 478     // Scan the partition followed by the sibling partition in the second half of the table
 479     removed += unlink_or_oops_do(cl, partition_begin, partition_end, worker_id);
 480     removed += unlink_or_oops_do(cl, table_half + partition_begin, table_half + partition_end, worker_id);
 481   }
 482 
 483   // Delayed update to avoid contention on the table lock
 484   if (removed > 0) {
 485     MutexLockerEx ml(StringDedupTable_lock, Mutex::_no_safepoint_check_flag);
 486     _table->_entries -= removed;
 487     _entries_removed += removed;
 488   }
 489 }
 490 
 491 uintx StringDedupTable::unlink_or_oops_do(StringDedupUnlinkOrOopsDoClosure* cl,
 492                                           size_t partition_begin,
 493                                           size_t partition_end,
 494                                           uint worker_id) {
 495   uintx removed = 0;
 496   for (size_t bucket = partition_begin; bucket < partition_end; bucket++) {
 497     StringDedupEntry** entry = _table->bucket(bucket);
 498     while (*entry != NULL) {
 499       oop* p = (oop*)(*entry)->obj_addr();
 500       if (cl->is_alive(*p)) {
 501         cl->keep_alive(p);
 502         if (is_resizing()) {
 503           // We are resizing the table, transfer entry to the new table
 504           _table->transfer(entry, _resized_table);
 505         } else {


< prev index next >