Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1StringDedup.hpp @ 20211:82693fb204a5
8038930: G1CodeRootSet::test fails with assert(_num_chunks_handed_out == 0) failed: No elements must have been handed out yet
Summary: The test incorrectly assumed that it had been started with no other previous compilation activity. Fix this by allowing multiple code root free chunk lists, and use one separate from the global one to perform the test.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Wed, 16 Apr 2014 10:14:50 +0200 |
parents | 1772223a25a2 |
children |
rev | line source |
---|---|
17764 | 1 /* |
2 * Copyright (c) 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 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUP_HPP | |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUP_HPP | |
27 | |
28 // | |
29 // String Deduplication | |
30 // | |
31 // String deduplication aims to reduce the heap live-set by deduplicating identical | |
32 // instances of String so that they share the same backing character array. | |
33 // | |
34 // The deduplication process is divided in two main parts, 1) finding the objects to | |
35 // deduplicate, and 2) deduplicating those objects. The first part is done as part of | |
36 // a normal GC cycle when objects are marked or evacuated. At this time a check is | |
37 // applied on each object to check if it is a candidate for deduplication. If so, the | |
38 // object is placed on the deduplication queue for later processing. The second part, | |
39 // processing the objects on the deduplication queue, is a concurrent phase which | |
40 // starts right after the stop-the-wold marking/evacuation phase. This phase is | |
41 // executed by the deduplication thread, which pulls deduplication candidates of the | |
42 // deduplication queue and tries to deduplicate them. | |
43 // | |
44 // A deduplication hashtable is used to keep track of all unique character arrays | |
45 // used by String objects. When deduplicating, a lookup is made in this table to see | |
46 // if there is already an identical character array somewhere on the heap. If so, the | |
47 // String object is adjusted to point to that character array, releasing the reference | |
48 // to the original array allowing it to eventually be garbage collected. If the lookup | |
49 // fails the character array is instead inserted into the hashtable so that this array | |
50 // can be shared at some point in the future. | |
51 // | |
52 // Candidate selection | |
53 // | |
54 // An object is considered a deduplication candidate if all of the following | |
55 // statements are true: | |
56 // | |
57 // - The object is an instance of java.lang.String | |
58 // | |
59 // - The object is being evacuated from a young heap region | |
60 // | |
61 // - The object is being evacuated to a young/survivor heap region and the | |
62 // object's age is equal to the deduplication age threshold | |
63 // | |
64 // or | |
65 // | |
66 // The object is being evacuated to an old heap region and the object's age is | |
67 // less than the deduplication age threshold | |
68 // | |
69 // Once an string object has been promoted to an old region, or its age is higher | |
70 // than the deduplication age threshold, is will never become a candidate again. | |
71 // This approach avoids making the same object a candidate more than once. | |
72 // | |
73 // Interned strings are a bit special. They are explicitly deduplicated just before | |
74 // being inserted into the StringTable (to avoid counteracting C2 optimizations done | |
75 // on string literals), then they also become deduplication candidates if they reach | |
76 // the deduplication age threshold or are evacuated to an old heap region. The second | |
77 // attempt to deduplicate such strings will be in vain, but we have no fast way of | |
78 // filtering them out. This has not shown to be a problem, as the number of interned | |
79 // strings is usually dwarfed by the number of normal (non-interned) strings. | |
80 // | |
81 // For additional information on string deduplication, please see JEP 192, | |
82 // http://openjdk.java.net/jeps/192 | |
83 // | |
84 | |
85 #include "memory/allocation.hpp" | |
86 #include "oops/oop.hpp" | |
87 | |
88 class OopClosure; | |
89 class BoolObjectClosure; | |
90 class ThreadClosure; | |
91 class outputStream; | |
92 class G1StringDedupTable; | |
93 | |
94 // | |
95 // Main interface for interacting with string deduplication. | |
96 // | |
97 class G1StringDedup : public AllStatic { | |
98 private: | |
99 // Single state for checking if both G1 and string deduplication is enabled. | |
100 static bool _enabled; | |
101 | |
102 // Candidate selection policies, returns true if the given object is | |
103 // candidate for string deduplication. | |
104 static bool is_candidate_from_mark(oop obj); | |
105 static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj); | |
106 | |
107 public: | |
108 // Returns true if both G1 and string deduplication is enabled. | |
109 static bool is_enabled() { | |
110 return _enabled; | |
111 } | |
112 | |
17947
1772223a25a2
8037112: gc/g1/TestHumongousAllocInitialMark.java caused SIGSEGV
pliden
parents:
17764
diff
changeset
|
113 // Initialize string deduplication. |
17764 | 114 static void initialize(); |
115 | |
17947
1772223a25a2
8037112: gc/g1/TestHumongousAllocInitialMark.java caused SIGSEGV
pliden
parents:
17764
diff
changeset
|
116 // Stop the deduplication thread. |
1772223a25a2
8037112: gc/g1/TestHumongousAllocInitialMark.java caused SIGSEGV
pliden
parents:
17764
diff
changeset
|
117 static void stop(); |
1772223a25a2
8037112: gc/g1/TestHumongousAllocInitialMark.java caused SIGSEGV
pliden
parents:
17764
diff
changeset
|
118 |
17764 | 119 // Immediately deduplicates the given String object, bypassing the |
120 // the deduplication queue. | |
121 static void deduplicate(oop java_string); | |
122 | |
123 // Enqueues a deduplication candidate for later processing by the deduplication | |
124 // thread. Before enqueuing, these functions apply the appropriate candidate | |
125 // selection policy to filters out non-candidates. | |
126 static void enqueue_from_mark(oop java_string); | |
127 static void enqueue_from_evacuation(bool from_young, bool to_young, | |
128 unsigned int queue, oop java_string); | |
129 | |
130 static void oops_do(OopClosure* keep_alive); | |
131 static void unlink(BoolObjectClosure* is_alive); | |
132 static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, | |
133 bool allow_resize_and_rehash = true); | |
134 | |
135 static void threads_do(ThreadClosure* tc); | |
136 static void print_worker_threads_on(outputStream* st); | |
137 static void verify(); | |
138 }; | |
139 | |
140 // | |
141 // This closure encapsulates the state and the closures needed when scanning | |
142 // the deduplication queue and table during the unlink_or_oops_do() operation. | |
143 // A single instance of this closure is created and then shared by all worker | |
144 // threads participating in the scan. The _next_queue and _next_bucket fields | |
145 // provide a simple mechanism for GC workers to claim exclusive access to a | |
146 // queue or a table partition. | |
147 // | |
148 class G1StringDedupUnlinkOrOopsDoClosure : public StackObj { | |
149 private: | |
150 BoolObjectClosure* _is_alive; | |
151 OopClosure* _keep_alive; | |
152 G1StringDedupTable* _resized_table; | |
153 G1StringDedupTable* _rehashed_table; | |
154 size_t _next_queue; | |
155 size_t _next_bucket; | |
156 | |
157 public: | |
158 G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive, | |
159 OopClosure* keep_alive, | |
160 bool allow_resize_and_rehash); | |
161 ~G1StringDedupUnlinkOrOopsDoClosure(); | |
162 | |
163 bool is_resizing() { | |
164 return _resized_table != NULL; | |
165 } | |
166 | |
167 G1StringDedupTable* resized_table() { | |
168 return _resized_table; | |
169 } | |
170 | |
171 bool is_rehashing() { | |
172 return _rehashed_table != NULL; | |
173 } | |
174 | |
175 // Atomically claims the next available queue for exclusive access by | |
176 // the current thread. Returns the queue number of the claimed queue. | |
177 size_t claim_queue() { | |
178 return (size_t)Atomic::add_ptr(1, &_next_queue) - 1; | |
179 } | |
180 | |
181 // Atomically claims the next available table partition for exclusive | |
182 // access by the current thread. Returns the table bucket number where | |
183 // the claimed partition starts. | |
184 size_t claim_table_partition(size_t partition_size) { | |
185 return (size_t)Atomic::add_ptr(partition_size, &_next_bucket) - partition_size; | |
186 } | |
187 | |
188 // Applies and returns the result from the is_alive closure, or | |
189 // returns true if no such closure was provided. | |
190 bool is_alive(oop o) { | |
191 if (_is_alive != NULL) { | |
192 return _is_alive->do_object_b(o); | |
193 } | |
194 return true; | |
195 } | |
196 | |
197 // Applies the keep_alive closure, or does nothing if no such | |
198 // closure was provided. | |
199 void keep_alive(oop* p) { | |
200 if (_keep_alive != NULL) { | |
201 _keep_alive->do_oop(p); | |
202 } | |
203 } | |
204 }; | |
205 | |
206 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUP_HPP |