Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/bufferingOopClosure.cpp @ 14355:937cf56dede6
8033764: Remove the usage of StarTask from BufferingOopClosure
Reviewed-by: mgerdin, brutisso, tschatzl
author | stefank |
---|---|
date | Mon, 10 Feb 2014 12:51:51 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
14353:7c41aaa3929b | 14355:937cf56dede6 |
---|---|
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 #include "precompiled.hpp" | |
26 #include "gc_implementation/g1/bufferingOopClosure.hpp" | |
27 #include "memory/iterator.hpp" | |
28 #include "utilities/debug.hpp" | |
29 | |
30 /////////////// Unit tests /////////////// | |
31 | |
32 #ifndef PRODUCT | |
33 | |
34 class TestBufferingOopClosure { | |
35 | |
36 // Helper class to fake a set of oop*s and narrowOop*s. | |
37 class FakeRoots { | |
38 public: | |
39 // Used for sanity checking of the values passed to the do_oops functions in the test. | |
40 static const uintptr_t NarrowOopMarker = uintptr_t(1) << (BitsPerWord -1); | |
41 | |
42 int _num_narrow; | |
43 int _num_full; | |
44 void** _narrow; | |
45 void** _full; | |
46 | |
47 FakeRoots(int num_narrow, int num_full) : | |
48 _num_narrow(num_narrow), | |
49 _num_full(num_full), | |
50 _narrow((void**)::malloc(sizeof(void*) * num_narrow)), | |
51 _full((void**)::malloc(sizeof(void*) * num_full)) { | |
52 | |
53 for (int i = 0; i < num_narrow; i++) { | |
54 _narrow[i] = (void*)(NarrowOopMarker + (uintptr_t)i); | |
55 } | |
56 for (int i = 0; i < num_full; i++) { | |
57 _full[i] = (void*)(uintptr_t)i; | |
58 } | |
59 } | |
60 | |
61 ~FakeRoots() { | |
62 ::free(_narrow); | |
63 ::free(_full); | |
64 } | |
65 | |
66 void oops_do_narrow_then_full(OopClosure* cl) { | |
67 for (int i = 0; i < _num_narrow; i++) { | |
68 cl->do_oop((narrowOop*)_narrow[i]); | |
69 } | |
70 for (int i = 0; i < _num_full; i++) { | |
71 cl->do_oop((oop*)_full[i]); | |
72 } | |
73 } | |
74 | |
75 void oops_do_full_then_narrow(OopClosure* cl) { | |
76 for (int i = 0; i < _num_full; i++) { | |
77 cl->do_oop((oop*)_full[i]); | |
78 } | |
79 for (int i = 0; i < _num_narrow; i++) { | |
80 cl->do_oop((narrowOop*)_narrow[i]); | |
81 } | |
82 } | |
83 | |
84 void oops_do_mixed(OopClosure* cl) { | |
85 int i; | |
86 for (i = 0; i < _num_full && i < _num_narrow; i++) { | |
87 cl->do_oop((oop*)_full[i]); | |
88 cl->do_oop((narrowOop*)_narrow[i]); | |
89 } | |
90 for (int j = i; j < _num_full; j++) { | |
91 cl->do_oop((oop*)_full[i]); | |
92 } | |
93 for (int j = i; j < _num_narrow; j++) { | |
94 cl->do_oop((narrowOop*)_narrow[i]); | |
95 } | |
96 } | |
97 | |
98 static const int MaxOrder = 2; | |
99 | |
100 void oops_do(OopClosure* cl, int do_oop_order) { | |
101 switch(do_oop_order) { | |
102 case 0: | |
103 oops_do_narrow_then_full(cl); | |
104 break; | |
105 case 1: | |
106 oops_do_full_then_narrow(cl); | |
107 break; | |
108 case 2: | |
109 oops_do_mixed(cl); | |
110 break; | |
111 default: | |
112 oops_do_narrow_then_full(cl); | |
113 break; | |
114 } | |
115 } | |
116 }; | |
117 | |
118 class CountOopClosure : public OopClosure { | |
119 int _narrow_oop_count; | |
120 int _full_oop_count; | |
121 public: | |
122 CountOopClosure() : _narrow_oop_count(0), _full_oop_count(0) {} | |
123 void do_oop(narrowOop* p) { | |
124 assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) != 0, | |
125 "The narrowOop was unexpectedly not marked with the NarrowOopMarker"); | |
126 _narrow_oop_count++; | |
127 } | |
128 | |
129 void do_oop(oop* p){ | |
130 assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) == 0, | |
131 "The oop was unexpectedly marked with the NarrowOopMarker"); | |
132 _full_oop_count++; | |
133 } | |
134 | |
135 int narrow_oop_count() { return _narrow_oop_count; } | |
136 int full_oop_count() { return _full_oop_count; } | |
137 int all_oop_count() { return _narrow_oop_count + _full_oop_count; } | |
138 }; | |
139 | |
140 class DoNothingOopClosure : public OopClosure { | |
141 public: | |
142 void do_oop(narrowOop* p) {} | |
143 void do_oop(oop* p) {} | |
144 }; | |
145 | |
146 static void testCount(int num_narrow, int num_full, int do_oop_order) { | |
147 FakeRoots fr(num_narrow, num_full); | |
148 | |
149 CountOopClosure coc; | |
150 BufferingOopClosure boc(&coc); | |
151 | |
152 fr.oops_do(&boc, do_oop_order); | |
153 | |
154 boc.done(); | |
155 | |
156 #define assert_testCount(got, expected) \ | |
157 assert((got) == (expected), \ | |
158 err_msg("Expected: %d, got: %d, when running testCount(%d, %d, %d)", \ | |
159 (got), (expected), num_narrow, num_full, do_oop_order)) | |
160 | |
161 assert_testCount(num_narrow, coc.narrow_oop_count()); | |
162 assert_testCount(num_full, coc.full_oop_count()); | |
163 assert_testCount(num_narrow + num_full, coc.all_oop_count()); | |
164 } | |
165 | |
166 static void testCount() { | |
167 int buffer_length = BufferingOopClosure::BufferLength; | |
168 | |
169 for (int order = 0; order < FakeRoots::MaxOrder; order++) { | |
170 testCount(0, 0, order); | |
171 testCount(10, 0, order); | |
172 testCount(0, 10, order); | |
173 testCount(10, 10, order); | |
174 testCount(buffer_length, 10, order); | |
175 testCount(10, buffer_length, order); | |
176 testCount(buffer_length, buffer_length, order); | |
177 testCount(buffer_length + 1, 10, order); | |
178 testCount(10, buffer_length + 1, order); | |
179 testCount(buffer_length + 1, buffer_length, order); | |
180 testCount(buffer_length, buffer_length + 1, order); | |
181 testCount(buffer_length + 1, buffer_length + 1, order); | |
182 } | |
183 } | |
184 | |
185 static void testIsBufferEmptyOrFull(int num_narrow, int num_full, bool expect_empty, bool expect_full) { | |
186 FakeRoots fr(num_narrow, num_full); | |
187 | |
188 DoNothingOopClosure cl; | |
189 BufferingOopClosure boc(&cl); | |
190 | |
191 fr.oops_do(&boc, 0); | |
192 | |
193 #define assert_testIsBufferEmptyOrFull(got, expected) \ | |
194 assert((got) == (expected), \ | |
195 err_msg("Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \ | |
196 (got), (expected), num_narrow, num_full, \ | |
197 BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full))) | |
198 | |
199 assert_testIsBufferEmptyOrFull(expect_empty, boc.is_buffer_empty()); | |
200 assert_testIsBufferEmptyOrFull(expect_full, boc.is_buffer_full()); | |
201 } | |
202 | |
203 static void testIsBufferEmptyOrFull() { | |
204 int bl = BufferingOopClosure::BufferLength; | |
205 | |
206 testIsBufferEmptyOrFull(0, 0, true, false); | |
207 testIsBufferEmptyOrFull(1, 0, false, false); | |
208 testIsBufferEmptyOrFull(0, 1, false, false); | |
209 testIsBufferEmptyOrFull(1, 1, false, false); | |
210 testIsBufferEmptyOrFull(10, 0, false, false); | |
211 testIsBufferEmptyOrFull(0, 10, false, false); | |
212 testIsBufferEmptyOrFull(10, 10, false, false); | |
213 testIsBufferEmptyOrFull(0, bl, false, true); | |
214 testIsBufferEmptyOrFull(bl, 0, false, true); | |
215 testIsBufferEmptyOrFull(bl/2, bl/2, false, true); | |
216 testIsBufferEmptyOrFull(bl-1, 1, false, true); | |
217 testIsBufferEmptyOrFull(1, bl-1, false, true); | |
218 // Processed | |
219 testIsBufferEmptyOrFull(bl+1, 0, false, false); | |
220 testIsBufferEmptyOrFull(bl*2, 0, false, true); | |
221 } | |
222 | |
223 static void testEmptyAfterDone(int num_narrow, int num_full) { | |
224 FakeRoots fr(num_narrow, num_full); | |
225 | |
226 DoNothingOopClosure cl; | |
227 BufferingOopClosure boc(&cl); | |
228 | |
229 fr.oops_do(&boc, 0); | |
230 | |
231 // Make sure all get processed. | |
232 boc.done(); | |
233 | |
234 assert(boc.is_buffer_empty(), | |
235 err_msg("Should be empty after call to done(). testEmptyAfterDone(%d, %d)", | |
236 num_narrow, num_full)); | |
237 } | |
238 | |
239 static void testEmptyAfterDone() { | |
240 int bl = BufferingOopClosure::BufferLength; | |
241 | |
242 testEmptyAfterDone(0, 0); | |
243 testEmptyAfterDone(1, 0); | |
244 testEmptyAfterDone(0, 1); | |
245 testEmptyAfterDone(1, 1); | |
246 testEmptyAfterDone(10, 0); | |
247 testEmptyAfterDone(0, 10); | |
248 testEmptyAfterDone(10, 10); | |
249 testEmptyAfterDone(0, bl); | |
250 testEmptyAfterDone(bl, 0); | |
251 testEmptyAfterDone(bl/2, bl/2); | |
252 testEmptyAfterDone(bl-1, 1); | |
253 testEmptyAfterDone(1, bl-1); | |
254 // Processed | |
255 testEmptyAfterDone(bl+1, 0); | |
256 testEmptyAfterDone(bl*2, 0); | |
257 } | |
258 | |
259 public: | |
260 static void test() { | |
261 testCount(); | |
262 testIsBufferEmptyOrFull(); | |
263 testEmptyAfterDone(); | |
264 } | |
265 }; | |
266 | |
267 void TestBufferingOopClosure_test() { | |
268 TestBufferingOopClosure::test(); | |
269 } | |
270 | |
271 #endif |