Mercurial > hg > truffle
annotate src/share/vm/utilities/hashtable.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 3582bf76420e |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP |
26 #define SHARE_VM_UTILITIES_HASHTABLE_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "oops/oop.hpp" | |
30 #include "oops/symbolOop.hpp" | |
31 #include "runtime/handles.hpp" | |
32 | |
0 | 33 // This is a generic hashtable, designed to be used for the symbol |
34 // and string tables. | |
35 // | |
36 // It is implemented as an open hash table with a fixed number of buckets. | |
37 // | |
38 // %note: | |
39 // - TableEntrys are allocated in blocks to reduce the space overhead. | |
40 | |
41 | |
42 | |
43 class BasicHashtableEntry : public CHeapObj { | |
44 friend class VMStructs; | |
45 private: | |
46 unsigned int _hash; // 32-bit hash for item | |
47 | |
48 // Link to next element in the linked list for this bucket. EXCEPT | |
49 // bit 0 set indicates that this entry is shared and must not be | |
50 // unlinked from the table. Bit 0 is set during the dumping of the | |
51 // archive. Since shared entries are immutable, _next fields in the | |
52 // shared entries will not change. New entries will always be | |
53 // unshared and since pointers are align, bit 0 will always remain 0 | |
54 // with no extra effort. | |
55 BasicHashtableEntry* _next; | |
56 | |
57 // Windows IA64 compiler requires subclasses to be able to access these | |
58 protected: | |
59 // Entry objects should not be created, they should be taken from the | |
60 // free list with BasicHashtable.new_entry(). | |
61 BasicHashtableEntry() { ShouldNotReachHere(); } | |
62 // Entry objects should not be destroyed. They should be placed on | |
63 // the free list instead with BasicHashtable.free_entry(). | |
64 ~BasicHashtableEntry() { ShouldNotReachHere(); } | |
65 | |
66 public: | |
67 | |
68 unsigned int hash() const { return _hash; } | |
69 void set_hash(unsigned int hash) { _hash = hash; } | |
70 unsigned int* hash_addr() { return &_hash; } | |
71 | |
72 static BasicHashtableEntry* make_ptr(BasicHashtableEntry* p) { | |
73 return (BasicHashtableEntry*)((intptr_t)p & -2); | |
74 } | |
75 | |
76 BasicHashtableEntry* next() const { | |
77 return make_ptr(_next); | |
78 } | |
79 | |
80 void set_next(BasicHashtableEntry* next) { | |
81 _next = next; | |
82 } | |
83 | |
84 BasicHashtableEntry** next_addr() { | |
85 return &_next; | |
86 } | |
87 | |
88 bool is_shared() const { | |
89 return ((intptr_t)_next & 1) != 0; | |
90 } | |
91 | |
92 void set_shared() { | |
93 _next = (BasicHashtableEntry*)((intptr_t)_next | 1); | |
94 } | |
95 }; | |
96 | |
97 | |
98 | |
99 class HashtableEntry : public BasicHashtableEntry { | |
100 friend class VMStructs; | |
101 private: | |
102 oop _literal; // ref to item in table. | |
103 | |
104 public: | |
105 // Literal | |
106 oop literal() const { return _literal; } | |
107 oop* literal_addr() { return &_literal; } | |
108 void set_literal(oop s) { _literal = s; } | |
109 | |
110 HashtableEntry* next() const { | |
111 return (HashtableEntry*)BasicHashtableEntry::next(); | |
112 } | |
113 HashtableEntry** next_addr() { | |
114 return (HashtableEntry**)BasicHashtableEntry::next_addr(); | |
115 } | |
116 }; | |
117 | |
118 | |
119 | |
120 class HashtableBucket : public CHeapObj { | |
121 friend class VMStructs; | |
122 private: | |
123 // Instance variable | |
124 BasicHashtableEntry* _entry; | |
125 | |
126 public: | |
127 // Accessing | |
128 void clear() { _entry = NULL; } | |
129 | |
130 // The following methods use order access methods to avoid race | |
131 // conditions in multiprocessor systems. | |
132 BasicHashtableEntry* get_entry() const; | |
133 void set_entry(BasicHashtableEntry* l); | |
134 | |
135 // The following method is not MT-safe and must be done under lock. | |
136 BasicHashtableEntry** entry_addr() { return &_entry; } | |
137 }; | |
138 | |
139 | |
140 class BasicHashtable : public CHeapObj { | |
141 friend class VMStructs; | |
142 | |
143 public: | |
144 BasicHashtable(int table_size, int entry_size); | |
145 BasicHashtable(int table_size, int entry_size, | |
146 HashtableBucket* buckets, int number_of_entries); | |
147 | |
148 // Sharing support. | |
149 void copy_buckets(char** top, char* end); | |
150 void copy_table(char** top, char* end); | |
151 | |
152 // Bucket handling | |
153 int hash_to_index(unsigned int full_hash) { | |
154 int h = full_hash % _table_size; | |
155 assert(h >= 0 && h < _table_size, "Illegal hash value"); | |
156 return h; | |
157 } | |
158 | |
159 // Reverse the order of elements in each of the buckets. | |
160 void reverse(); | |
161 | |
162 private: | |
163 // Instance variables | |
164 int _table_size; | |
165 HashtableBucket* _buckets; | |
166 BasicHashtableEntry* _free_list; | |
167 char* _first_free_entry; | |
168 char* _end_block; | |
169 int _entry_size; | |
170 int _number_of_entries; | |
171 | |
172 protected: | |
173 | |
174 #ifdef ASSERT | |
175 int _lookup_count; | |
176 int _lookup_length; | |
177 void verify_lookup_length(double load); | |
178 #endif | |
179 | |
180 void initialize(int table_size, int entry_size, int number_of_entries); | |
181 | |
182 // Accessor | |
183 int entry_size() const { return _entry_size; } | |
184 int table_size() { return _table_size; } | |
185 | |
186 // The following method is MT-safe and may be used with caution. | |
187 BasicHashtableEntry* bucket(int i); | |
188 | |
189 // The following method is not MT-safe and must be done under lock. | |
190 BasicHashtableEntry** bucket_addr(int i) { return _buckets[i].entry_addr(); } | |
191 | |
192 // Table entry management | |
193 BasicHashtableEntry* new_entry(unsigned int hashValue); | |
194 | |
195 public: | |
196 void set_entry(int index, BasicHashtableEntry* entry); | |
197 | |
198 void add_entry(int index, BasicHashtableEntry* entry); | |
199 | |
200 void free_entry(BasicHashtableEntry* entry); | |
201 | |
202 int number_of_entries() { return _number_of_entries; } | |
203 | |
204 void verify() PRODUCT_RETURN; | |
205 }; | |
206 | |
207 | |
208 class Hashtable : public BasicHashtable { | |
209 friend class VMStructs; | |
210 | |
211 public: | |
212 Hashtable(int table_size, int entry_size) | |
213 : BasicHashtable(table_size, entry_size) { } | |
214 | |
215 Hashtable(int table_size, int entry_size, | |
216 HashtableBucket* buckets, int number_of_entries) | |
217 : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { } | |
218 | |
219 // Invoke "f->do_oop" on the locations of all oops in the table. | |
220 void oops_do(OopClosure* f); | |
221 | |
222 // Debugging | |
223 void print() PRODUCT_RETURN; | |
224 | |
225 // GC support | |
226 // Delete pointers to otherwise-unreachable objects. | |
227 void unlink(BoolObjectClosure* cl); | |
228 | |
229 // Reverse the order of elements in each of the buckets. Hashtable | |
230 // entries which refer to objects at a lower address than 'boundary' | |
231 // are separated from those which refer to objects at higher | |
232 // addresses, and appear first in the list. | |
233 void reverse(void* boundary = NULL); | |
234 | |
235 protected: | |
236 | |
237 static unsigned int hash_symbol(const char* s, int len); | |
238 | |
239 unsigned int compute_hash(symbolHandle name) { | |
240 return (unsigned int) name->identity_hash(); | |
241 } | |
242 | |
243 int index_for(symbolHandle name) { | |
244 return hash_to_index(compute_hash(name)); | |
245 } | |
246 | |
247 // Table entry management | |
248 HashtableEntry* new_entry(unsigned int hashValue, oop obj); | |
249 | |
250 // The following method is MT-safe and may be used with caution. | |
251 HashtableEntry* bucket(int i) { | |
252 return (HashtableEntry*)BasicHashtable::bucket(i); | |
253 } | |
254 | |
255 // The following method is not MT-safe and must be done under lock. | |
256 HashtableEntry** bucket_addr(int i) { | |
257 return (HashtableEntry**)BasicHashtable::bucket_addr(i); | |
258 } | |
259 }; | |
260 | |
261 | |
262 // Verions of hashtable where two handles are used to compute the index. | |
263 | |
264 class TwoOopHashtable : public Hashtable { | |
265 friend class VMStructs; | |
266 protected: | |
267 TwoOopHashtable(int table_size, int entry_size) | |
268 : Hashtable(table_size, entry_size) {} | |
269 | |
270 TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t, | |
271 int number_of_entries) | |
272 : Hashtable(table_size, entry_size, t, number_of_entries) {} | |
273 | |
274 public: | |
275 unsigned int compute_hash(symbolHandle name, Handle loader) { | |
276 // Be careful with identity_hash(), it can safepoint and if this | |
277 // were one expression, the compiler could choose to unhandle each | |
278 // oop before calling identity_hash() for either of them. If the first | |
279 // causes a GC, the next would fail. | |
280 unsigned int name_hash = name->identity_hash(); | |
281 unsigned int loader_hash = loader.is_null() ? 0 : loader->identity_hash(); | |
282 return name_hash ^ loader_hash; | |
283 } | |
284 | |
285 int index_for(symbolHandle name, Handle loader) { | |
286 return hash_to_index(compute_hash(name, loader)); | |
287 } | |
288 }; | |
1972 | 289 |
290 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP |