src/share/vm/classfile/symbolTable.cpp

Print this page
rev 6140 : 8029075: String deduplication in G1
Implementation of JEP 192, http://openjdk.java.net/jeps/192
   1 /*
   2  * Copyright (c) 1997, 2013, 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.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc_interface/collectedHeap.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/filemap.hpp"
  33 #include "memory/gcLocker.inline.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/oop.inline2.hpp"
  36 #include "runtime/mutexLocker.hpp"
  37 #include "utilities/hashtable.inline.hpp"



  38 
  39 // --------------------------------------------------------------------------
  40 
  41 // the number of buckets a thread claims
  42 const int ClaimChunkSize = 32;
  43 
  44 SymbolTable* SymbolTable::_the_table = NULL;
  45 // Static arena for symbols that are not deallocated
  46 Arena* SymbolTable::_arena = NULL;
  47 bool SymbolTable::_needs_rehashing = false;
  48 
  49 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
  50   assert (len <= Symbol::max_length(), "should be checked by caller");
  51 
  52   Symbol* sym;
  53 
  54   if (DumpSharedSpaces) {
  55     // Allocate all symbols to CLD shared metaspace
  56     sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
  57   } else if (c_heap) {


 711                         int len, TRAPS) {
 712   unsigned int hashValue = hash_string(name, len);
 713   int index = the_table()->hash_to_index(hashValue);
 714   oop found_string = the_table()->lookup(index, name, len, hashValue);
 715 
 716   // Found
 717   if (found_string != NULL) return found_string;
 718 
 719   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 720   assert(!Universe::heap()->is_in_reserved(name),
 721          "proposed name of symbol must be stable");
 722 
 723   Handle string;
 724   // try to reuse the string if possible
 725   if (!string_or_null.is_null()) {
 726     string = string_or_null;
 727   } else {
 728     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 729   }
 730 









 731   // Grab the StringTable_lock before getting the_table() because it could
 732   // change at safepoint.
 733   MutexLocker ml(StringTable_lock, THREAD);
 734 
 735   // Otherwise, add to symbol to table
 736   return the_table()->basic_add(index, string, name, len,
 737                                 hashValue, CHECK_NULL);
 738 }
 739 
 740 oop StringTable::intern(Symbol* symbol, TRAPS) {
 741   if (symbol == NULL) return NULL;
 742   ResourceMark rm(THREAD);
 743   int length;
 744   jchar* chars = symbol->as_unicode(length);
 745   Handle string;
 746   oop result = intern(string, chars, length, CHECK_NULL);
 747   return result;
 748 }
 749 
 750 


   1 /*
   2  * Copyright (c) 1997, 2014, 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.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc_interface/collectedHeap.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/filemap.hpp"
  33 #include "memory/gcLocker.inline.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/oop.inline2.hpp"
  36 #include "runtime/mutexLocker.hpp"
  37 #include "utilities/hashtable.inline.hpp"
  38 #if INCLUDE_ALL_GCS
  39 #include "gc_implementation/g1/g1StringDedup.hpp"
  40 #endif
  41 
  42 // --------------------------------------------------------------------------
  43 
  44 // the number of buckets a thread claims
  45 const int ClaimChunkSize = 32;
  46 
  47 SymbolTable* SymbolTable::_the_table = NULL;
  48 // Static arena for symbols that are not deallocated
  49 Arena* SymbolTable::_arena = NULL;
  50 bool SymbolTable::_needs_rehashing = false;
  51 
  52 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
  53   assert (len <= Symbol::max_length(), "should be checked by caller");
  54 
  55   Symbol* sym;
  56 
  57   if (DumpSharedSpaces) {
  58     // Allocate all symbols to CLD shared metaspace
  59     sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
  60   } else if (c_heap) {


 714                         int len, TRAPS) {
 715   unsigned int hashValue = hash_string(name, len);
 716   int index = the_table()->hash_to_index(hashValue);
 717   oop found_string = the_table()->lookup(index, name, len, hashValue);
 718 
 719   // Found
 720   if (found_string != NULL) return found_string;
 721 
 722   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 723   assert(!Universe::heap()->is_in_reserved(name),
 724          "proposed name of symbol must be stable");
 725 
 726   Handle string;
 727   // try to reuse the string if possible
 728   if (!string_or_null.is_null()) {
 729     string = string_or_null;
 730   } else {
 731     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 732   }
 733 
 734 #if INCLUDE_ALL_GCS
 735   if (G1StringDedup::is_enabled()) {
 736     // Deduplicate the string before it is interned. Note that we should never
 737     // deduplicate a string after it has been interned. Doing so will counteract
 738     // compiler optimizations done on e.g. interned string literals.
 739     G1StringDedup::deduplicate(string());
 740   }
 741 #endif
 742 
 743   // Grab the StringTable_lock before getting the_table() because it could
 744   // change at safepoint.
 745   MutexLocker ml(StringTable_lock, THREAD);
 746 
 747   // Otherwise, add to symbol to table
 748   return the_table()->basic_add(index, string, name, len,
 749                                 hashValue, CHECK_NULL);
 750 }
 751 
 752 oop StringTable::intern(Symbol* symbol, TRAPS) {
 753   if (symbol == NULL) return NULL;
 754   ResourceMark rm(THREAD);
 755   int length;
 756   jchar* chars = symbol->as_unicode(length);
 757   Handle string;
 758   oop result = intern(string, chars, length, CHECK_NULL);
 759   return result;
 760 }
 761 
 762