src/share/vm/gc_implementation/g1/g1StringDedupTable.hpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 0
f90c822e73f8
child 8452
04a62a3d51d7
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUPTABLE_HPP
aoqi@0 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUPTABLE_HPP
aoqi@0 27
aoqi@0 28 #include "gc_implementation/g1/g1StringDedupStat.hpp"
aoqi@0 29 #include "runtime/mutexLocker.hpp"
aoqi@0 30
aoqi@0 31 class G1StringDedupEntryCache;
aoqi@0 32
aoqi@0 33 //
aoqi@0 34 // Table entry in the deduplication hashtable. Points weakly to the
aoqi@0 35 // character array. Can be chained in a linked list in case of hash
aoqi@0 36 // collisions or when placed in a freelist in the entry cache.
aoqi@0 37 //
aoqi@0 38 class G1StringDedupEntry : public CHeapObj<mtGC> {
aoqi@0 39 private:
aoqi@0 40 G1StringDedupEntry* _next;
aoqi@0 41 unsigned int _hash;
aoqi@0 42 typeArrayOop _obj;
aoqi@0 43
aoqi@0 44 public:
aoqi@0 45 G1StringDedupEntry() :
aoqi@0 46 _next(NULL),
aoqi@0 47 _hash(0),
aoqi@0 48 _obj(NULL) {
aoqi@0 49 }
aoqi@0 50
aoqi@0 51 G1StringDedupEntry* next() {
aoqi@0 52 return _next;
aoqi@0 53 }
aoqi@0 54
aoqi@0 55 G1StringDedupEntry** next_addr() {
aoqi@0 56 return &_next;
aoqi@0 57 }
aoqi@0 58
aoqi@0 59 void set_next(G1StringDedupEntry* next) {
aoqi@0 60 _next = next;
aoqi@0 61 }
aoqi@0 62
aoqi@0 63 unsigned int hash() {
aoqi@0 64 return _hash;
aoqi@0 65 }
aoqi@0 66
aoqi@0 67 void set_hash(unsigned int hash) {
aoqi@0 68 _hash = hash;
aoqi@0 69 }
aoqi@0 70
aoqi@0 71 typeArrayOop obj() {
aoqi@0 72 return _obj;
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 typeArrayOop* obj_addr() {
aoqi@0 76 return &_obj;
aoqi@0 77 }
aoqi@0 78
aoqi@0 79 void set_obj(typeArrayOop obj) {
aoqi@0 80 _obj = obj;
aoqi@0 81 }
aoqi@0 82 };
aoqi@0 83
aoqi@0 84 //
aoqi@0 85 // The deduplication hashtable keeps track of all unique character arrays used
aoqi@0 86 // by String objects. Each table entry weakly points to an character array, allowing
aoqi@0 87 // otherwise unreachable character arrays to be declared dead and pruned from the
aoqi@0 88 // table.
aoqi@0 89 //
aoqi@0 90 // The table is dynamically resized to accommodate the current number of table entries.
aoqi@0 91 // The table has hash buckets with chains for hash collision. If the average chain
aoqi@0 92 // length goes above or below given thresholds the table grows or shrinks accordingly.
aoqi@0 93 //
aoqi@0 94 // The table is also dynamically rehashed (using a new hash seed) if it becomes severely
aoqi@0 95 // unbalanced, i.e., a hash chain is significantly longer than average.
aoqi@0 96 //
aoqi@0 97 // All access to the table is protected by the StringDedupTable_lock, except under
aoqi@0 98 // safepoints in which case GC workers are allowed to access a table partitions they
aoqi@0 99 // have claimed without first acquiring the lock. Note however, that this applies only
aoqi@0 100 // the table partition (i.e. a range of elements in _buckets), not other parts of the
aoqi@0 101 // table such as the _entries field, statistics counters, etc.
aoqi@0 102 //
aoqi@0 103 class G1StringDedupTable : public CHeapObj<mtGC> {
aoqi@0 104 private:
aoqi@0 105 // The currently active hashtable instance. Only modified when
aoqi@0 106 // the table is resizes or rehashed.
aoqi@0 107 static G1StringDedupTable* _table;
aoqi@0 108
aoqi@0 109 // Cache for reuse and fast alloc/free of table entries.
aoqi@0 110 static G1StringDedupEntryCache* _entry_cache;
aoqi@0 111
aoqi@0 112 G1StringDedupEntry** _buckets;
aoqi@0 113 size_t _size;
aoqi@0 114 uintx _entries;
aoqi@0 115 uintx _shrink_threshold;
aoqi@0 116 uintx _grow_threshold;
aoqi@0 117 bool _rehash_needed;
aoqi@0 118
aoqi@0 119 // The hash seed also dictates which hash function to use. A
aoqi@0 120 // zero hash seed means we will use the Java compatible hash
aoqi@0 121 // function (which doesn't use a seed), and a non-zero hash
aoqi@0 122 // seed means we use the murmur3 hash function.
aoqi@0 123 jint _hash_seed;
aoqi@0 124
aoqi@0 125 // Constants governing table resize/rehash/cache.
aoqi@0 126 static const size_t _min_size;
aoqi@0 127 static const size_t _max_size;
aoqi@0 128 static const double _grow_load_factor;
aoqi@0 129 static const double _shrink_load_factor;
aoqi@0 130 static const uintx _rehash_multiple;
aoqi@0 131 static const uintx _rehash_threshold;
aoqi@0 132 static const double _max_cache_factor;
aoqi@0 133
aoqi@0 134 // Table statistics, only used for logging.
aoqi@0 135 static uintx _entries_added;
aoqi@0 136 static uintx _entries_removed;
aoqi@0 137 static uintx _resize_count;
aoqi@0 138 static uintx _rehash_count;
aoqi@0 139
aoqi@0 140 G1StringDedupTable(size_t size, jint hash_seed = 0);
aoqi@0 141 ~G1StringDedupTable();
aoqi@0 142
aoqi@0 143 // Returns the hash bucket at the given index.
aoqi@0 144 G1StringDedupEntry** bucket(size_t index) {
aoqi@0 145 return _buckets + index;
aoqi@0 146 }
aoqi@0 147
aoqi@0 148 // Returns the hash bucket index for the given hash code.
aoqi@0 149 size_t hash_to_index(unsigned int hash) {
aoqi@0 150 return (size_t)hash & (_size - 1);
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 // Adds a new table entry to the given hash bucket.
aoqi@0 154 void add(typeArrayOop value, unsigned int hash, G1StringDedupEntry** list);
aoqi@0 155
aoqi@0 156 // Removes the given table entry from the table.
aoqi@0 157 void remove(G1StringDedupEntry** pentry, uint worker_id);
aoqi@0 158
aoqi@0 159 // Transfers a table entry from the current table to the destination table.
aoqi@0 160 void transfer(G1StringDedupEntry** pentry, G1StringDedupTable* dest);
aoqi@0 161
aoqi@0 162 // Returns an existing character array in the given hash bucket, or NULL
aoqi@0 163 // if no matching character array exists.
aoqi@0 164 typeArrayOop lookup(typeArrayOop value, unsigned int hash,
aoqi@0 165 G1StringDedupEntry** list, uintx &count);
aoqi@0 166
aoqi@0 167 // Returns an existing character array in the table, or inserts a new
aoqi@0 168 // table entry if no matching character array exists.
aoqi@0 169 typeArrayOop lookup_or_add_inner(typeArrayOop value, unsigned int hash);
aoqi@0 170
aoqi@0 171 // Thread safe lookup or add of table entry
aoqi@0 172 static typeArrayOop lookup_or_add(typeArrayOop value, unsigned int hash) {
aoqi@0 173 // Protect the table from concurrent access. Also note that this lock
aoqi@0 174 // acts as a fence for _table, which could have been replaced by a new
aoqi@0 175 // instance if the table was resized or rehashed.
aoqi@0 176 MutexLockerEx ml(StringDedupTable_lock, Mutex::_no_safepoint_check_flag);
aoqi@0 177 return _table->lookup_or_add_inner(value, hash);
aoqi@0 178 }
aoqi@0 179
aoqi@0 180 // Returns true if the hashtable is currently using a Java compatible
aoqi@0 181 // hash function.
aoqi@0 182 static bool use_java_hash() {
aoqi@0 183 return _table->_hash_seed == 0;
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 static bool equals(typeArrayOop value1, typeArrayOop value2);
aoqi@0 187
aoqi@0 188 // Computes the hash code for the given character array, using the
aoqi@0 189 // currently active hash function and hash seed.
aoqi@0 190 static unsigned int hash_code(typeArrayOop value);
aoqi@0 191
aoqi@0 192 static uintx unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl,
aoqi@0 193 size_t partition_begin,
aoqi@0 194 size_t partition_end,
aoqi@0 195 uint worker_id);
aoqi@0 196
aoqi@0 197 public:
aoqi@0 198 static void create();
aoqi@0 199
aoqi@0 200 // Deduplicates the given String object, or adds its backing
aoqi@0 201 // character array to the deduplication hashtable.
aoqi@0 202 static void deduplicate(oop java_string, G1StringDedupStat& stat);
aoqi@0 203
aoqi@0 204 // If a table resize is needed, returns a newly allocated empty
aoqi@0 205 // hashtable of the proper size.
aoqi@0 206 static G1StringDedupTable* prepare_resize();
aoqi@0 207
aoqi@0 208 // Installs a newly resized table as the currently active table
aoqi@0 209 // and deletes the previously active table.
aoqi@0 210 static void finish_resize(G1StringDedupTable* resized_table);
aoqi@0 211
aoqi@0 212 // If a table rehash is needed, returns a newly allocated empty
aoqi@0 213 // hashtable and updates the hash seed.
aoqi@0 214 static G1StringDedupTable* prepare_rehash();
aoqi@0 215
aoqi@0 216 // Transfers rehashed entries from the currently active table into
aoqi@0 217 // the new table. Installs the new table as the currently active table
aoqi@0 218 // and deletes the previously active table.
aoqi@0 219 static void finish_rehash(G1StringDedupTable* rehashed_table);
aoqi@0 220
aoqi@0 221 // If the table entry cache has grown too large, trim it down according to policy
aoqi@0 222 static void trim_entry_cache();
aoqi@0 223
aoqi@0 224 static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl, uint worker_id);
aoqi@0 225
aoqi@0 226 static void print_statistics(outputStream* st);
aoqi@0 227 static void verify();
aoqi@0 228 };
aoqi@0 229
aoqi@0 230 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUPTABLE_HPP

mercurial