1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/g1/bufferingOopClosure.cpp Mon Feb 10 12:51:51 2014 +0100 1.3 @@ -0,0 +1,271 @@ 1.4 +/* 1.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "gc_implementation/g1/bufferingOopClosure.hpp" 1.30 +#include "memory/iterator.hpp" 1.31 +#include "utilities/debug.hpp" 1.32 + 1.33 +/////////////// Unit tests /////////////// 1.34 + 1.35 +#ifndef PRODUCT 1.36 + 1.37 +class TestBufferingOopClosure { 1.38 + 1.39 + // Helper class to fake a set of oop*s and narrowOop*s. 1.40 + class FakeRoots { 1.41 + public: 1.42 + // Used for sanity checking of the values passed to the do_oops functions in the test. 1.43 + static const uintptr_t NarrowOopMarker = uintptr_t(1) << (BitsPerWord -1); 1.44 + 1.45 + int _num_narrow; 1.46 + int _num_full; 1.47 + void** _narrow; 1.48 + void** _full; 1.49 + 1.50 + FakeRoots(int num_narrow, int num_full) : 1.51 + _num_narrow(num_narrow), 1.52 + _num_full(num_full), 1.53 + _narrow((void**)::malloc(sizeof(void*) * num_narrow)), 1.54 + _full((void**)::malloc(sizeof(void*) * num_full)) { 1.55 + 1.56 + for (int i = 0; i < num_narrow; i++) { 1.57 + _narrow[i] = (void*)(NarrowOopMarker + (uintptr_t)i); 1.58 + } 1.59 + for (int i = 0; i < num_full; i++) { 1.60 + _full[i] = (void*)(uintptr_t)i; 1.61 + } 1.62 + } 1.63 + 1.64 + ~FakeRoots() { 1.65 + ::free(_narrow); 1.66 + ::free(_full); 1.67 + } 1.68 + 1.69 + void oops_do_narrow_then_full(OopClosure* cl) { 1.70 + for (int i = 0; i < _num_narrow; i++) { 1.71 + cl->do_oop((narrowOop*)_narrow[i]); 1.72 + } 1.73 + for (int i = 0; i < _num_full; i++) { 1.74 + cl->do_oop((oop*)_full[i]); 1.75 + } 1.76 + } 1.77 + 1.78 + void oops_do_full_then_narrow(OopClosure* cl) { 1.79 + for (int i = 0; i < _num_full; i++) { 1.80 + cl->do_oop((oop*)_full[i]); 1.81 + } 1.82 + for (int i = 0; i < _num_narrow; i++) { 1.83 + cl->do_oop((narrowOop*)_narrow[i]); 1.84 + } 1.85 + } 1.86 + 1.87 + void oops_do_mixed(OopClosure* cl) { 1.88 + int i; 1.89 + for (i = 0; i < _num_full && i < _num_narrow; i++) { 1.90 + cl->do_oop((oop*)_full[i]); 1.91 + cl->do_oop((narrowOop*)_narrow[i]); 1.92 + } 1.93 + for (int j = i; j < _num_full; j++) { 1.94 + cl->do_oop((oop*)_full[i]); 1.95 + } 1.96 + for (int j = i; j < _num_narrow; j++) { 1.97 + cl->do_oop((narrowOop*)_narrow[i]); 1.98 + } 1.99 + } 1.100 + 1.101 + static const int MaxOrder = 2; 1.102 + 1.103 + void oops_do(OopClosure* cl, int do_oop_order) { 1.104 + switch(do_oop_order) { 1.105 + case 0: 1.106 + oops_do_narrow_then_full(cl); 1.107 + break; 1.108 + case 1: 1.109 + oops_do_full_then_narrow(cl); 1.110 + break; 1.111 + case 2: 1.112 + oops_do_mixed(cl); 1.113 + break; 1.114 + default: 1.115 + oops_do_narrow_then_full(cl); 1.116 + break; 1.117 + } 1.118 + } 1.119 + }; 1.120 + 1.121 + class CountOopClosure : public OopClosure { 1.122 + int _narrow_oop_count; 1.123 + int _full_oop_count; 1.124 + public: 1.125 + CountOopClosure() : _narrow_oop_count(0), _full_oop_count(0) {} 1.126 + void do_oop(narrowOop* p) { 1.127 + assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) != 0, 1.128 + "The narrowOop was unexpectedly not marked with the NarrowOopMarker"); 1.129 + _narrow_oop_count++; 1.130 + } 1.131 + 1.132 + void do_oop(oop* p){ 1.133 + assert((uintptr_t(p) & FakeRoots::NarrowOopMarker) == 0, 1.134 + "The oop was unexpectedly marked with the NarrowOopMarker"); 1.135 + _full_oop_count++; 1.136 + } 1.137 + 1.138 + int narrow_oop_count() { return _narrow_oop_count; } 1.139 + int full_oop_count() { return _full_oop_count; } 1.140 + int all_oop_count() { return _narrow_oop_count + _full_oop_count; } 1.141 + }; 1.142 + 1.143 + class DoNothingOopClosure : public OopClosure { 1.144 + public: 1.145 + void do_oop(narrowOop* p) {} 1.146 + void do_oop(oop* p) {} 1.147 + }; 1.148 + 1.149 + static void testCount(int num_narrow, int num_full, int do_oop_order) { 1.150 + FakeRoots fr(num_narrow, num_full); 1.151 + 1.152 + CountOopClosure coc; 1.153 + BufferingOopClosure boc(&coc); 1.154 + 1.155 + fr.oops_do(&boc, do_oop_order); 1.156 + 1.157 + boc.done(); 1.158 + 1.159 + #define assert_testCount(got, expected) \ 1.160 + assert((got) == (expected), \ 1.161 + err_msg("Expected: %d, got: %d, when running testCount(%d, %d, %d)", \ 1.162 + (got), (expected), num_narrow, num_full, do_oop_order)) 1.163 + 1.164 + assert_testCount(num_narrow, coc.narrow_oop_count()); 1.165 + assert_testCount(num_full, coc.full_oop_count()); 1.166 + assert_testCount(num_narrow + num_full, coc.all_oop_count()); 1.167 + } 1.168 + 1.169 + static void testCount() { 1.170 + int buffer_length = BufferingOopClosure::BufferLength; 1.171 + 1.172 + for (int order = 0; order < FakeRoots::MaxOrder; order++) { 1.173 + testCount(0, 0, order); 1.174 + testCount(10, 0, order); 1.175 + testCount(0, 10, order); 1.176 + testCount(10, 10, order); 1.177 + testCount(buffer_length, 10, order); 1.178 + testCount(10, buffer_length, order); 1.179 + testCount(buffer_length, buffer_length, order); 1.180 + testCount(buffer_length + 1, 10, order); 1.181 + testCount(10, buffer_length + 1, order); 1.182 + testCount(buffer_length + 1, buffer_length, order); 1.183 + testCount(buffer_length, buffer_length + 1, order); 1.184 + testCount(buffer_length + 1, buffer_length + 1, order); 1.185 + } 1.186 + } 1.187 + 1.188 + static void testIsBufferEmptyOrFull(int num_narrow, int num_full, bool expect_empty, bool expect_full) { 1.189 + FakeRoots fr(num_narrow, num_full); 1.190 + 1.191 + DoNothingOopClosure cl; 1.192 + BufferingOopClosure boc(&cl); 1.193 + 1.194 + fr.oops_do(&boc, 0); 1.195 + 1.196 + #define assert_testIsBufferEmptyOrFull(got, expected) \ 1.197 + assert((got) == (expected), \ 1.198 + err_msg("Expected: %d, got: %d. testIsBufferEmptyOrFull(%d, %d, %s, %s)", \ 1.199 + (got), (expected), num_narrow, num_full, \ 1.200 + BOOL_TO_STR(expect_empty), BOOL_TO_STR(expect_full))) 1.201 + 1.202 + assert_testIsBufferEmptyOrFull(expect_empty, boc.is_buffer_empty()); 1.203 + assert_testIsBufferEmptyOrFull(expect_full, boc.is_buffer_full()); 1.204 + } 1.205 + 1.206 + static void testIsBufferEmptyOrFull() { 1.207 + int bl = BufferingOopClosure::BufferLength; 1.208 + 1.209 + testIsBufferEmptyOrFull(0, 0, true, false); 1.210 + testIsBufferEmptyOrFull(1, 0, false, false); 1.211 + testIsBufferEmptyOrFull(0, 1, false, false); 1.212 + testIsBufferEmptyOrFull(1, 1, false, false); 1.213 + testIsBufferEmptyOrFull(10, 0, false, false); 1.214 + testIsBufferEmptyOrFull(0, 10, false, false); 1.215 + testIsBufferEmptyOrFull(10, 10, false, false); 1.216 + testIsBufferEmptyOrFull(0, bl, false, true); 1.217 + testIsBufferEmptyOrFull(bl, 0, false, true); 1.218 + testIsBufferEmptyOrFull(bl/2, bl/2, false, true); 1.219 + testIsBufferEmptyOrFull(bl-1, 1, false, true); 1.220 + testIsBufferEmptyOrFull(1, bl-1, false, true); 1.221 + // Processed 1.222 + testIsBufferEmptyOrFull(bl+1, 0, false, false); 1.223 + testIsBufferEmptyOrFull(bl*2, 0, false, true); 1.224 + } 1.225 + 1.226 + static void testEmptyAfterDone(int num_narrow, int num_full) { 1.227 + FakeRoots fr(num_narrow, num_full); 1.228 + 1.229 + DoNothingOopClosure cl; 1.230 + BufferingOopClosure boc(&cl); 1.231 + 1.232 + fr.oops_do(&boc, 0); 1.233 + 1.234 + // Make sure all get processed. 1.235 + boc.done(); 1.236 + 1.237 + assert(boc.is_buffer_empty(), 1.238 + err_msg("Should be empty after call to done(). testEmptyAfterDone(%d, %d)", 1.239 + num_narrow, num_full)); 1.240 + } 1.241 + 1.242 + static void testEmptyAfterDone() { 1.243 + int bl = BufferingOopClosure::BufferLength; 1.244 + 1.245 + testEmptyAfterDone(0, 0); 1.246 + testEmptyAfterDone(1, 0); 1.247 + testEmptyAfterDone(0, 1); 1.248 + testEmptyAfterDone(1, 1); 1.249 + testEmptyAfterDone(10, 0); 1.250 + testEmptyAfterDone(0, 10); 1.251 + testEmptyAfterDone(10, 10); 1.252 + testEmptyAfterDone(0, bl); 1.253 + testEmptyAfterDone(bl, 0); 1.254 + testEmptyAfterDone(bl/2, bl/2); 1.255 + testEmptyAfterDone(bl-1, 1); 1.256 + testEmptyAfterDone(1, bl-1); 1.257 + // Processed 1.258 + testEmptyAfterDone(bl+1, 0); 1.259 + testEmptyAfterDone(bl*2, 0); 1.260 + } 1.261 + 1.262 + public: 1.263 + static void test() { 1.264 + testCount(); 1.265 + testIsBufferEmptyOrFull(); 1.266 + testEmptyAfterDone(); 1.267 + } 1.268 +}; 1.269 + 1.270 +void TestBufferingOopClosure_test() { 1.271 + TestBufferingOopClosure::test(); 1.272 +} 1.273 + 1.274 +#endif