jdk

Форк
0
/
test_bitMap_setops.cpp 
422 строки · 12.2 Кб
1
/*
2
 * Copyright (c) 2016, 2019, 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
#include "precompiled.hpp"
25
#include "runtime/os.hpp"
26
#include "utilities/align.hpp"
27
#include "utilities/bitMap.inline.hpp"
28
#include "utilities/copy.hpp"
29
#include "utilities/debug.hpp"
30
#include "utilities/globalDefinitions.hpp"
31
#include "unittest.hpp"
32

33
#include <stdlib.h>
34

35
typedef BitMap::idx_t idx_t;
36
typedef BitMap::bm_word_t bm_word_t;
37

38
inline idx_t word_align_down(idx_t bit) {
39
  return align_down(bit, BitsPerWord);
40
}
41

42
class BitMapMemory {
43
private:
44
  idx_t _words;
45
  bm_word_t* _memory;
46

47
public:
48
  BitMapMemory(idx_t bits) :
49
    _words(BitMap::calc_size_in_words(bits)),
50
    _memory(static_cast<bm_word_t*>(os::malloc(_words * sizeof(bm_word_t), mtTest)))
51
  { }
52

53
  ~BitMapMemory() {
54
    os::free(_memory);
55
  }
56

57
  BitMapView make_view(idx_t bits, bm_word_t value) {
58
    vmassert(BitMap::calc_size_in_words(bits) <= _words, "invalid request");
59
    STATIC_ASSERT(sizeof(bm_word_t) == sizeof(HeapWord));
60
    Copy::fill_to_aligned_words((HeapWord*)_memory, _words, value);
61
    return BitMapView(_memory, bits);
62
  }
63

64
  bm_word_t* memory() { return _memory; }
65
};
66

67
const idx_t aligned_size = 4 * BitsPerWord;
68
const idx_t unaligned_size = aligned_size - (BitsPerWord / 2);
69

70
static bm_word_t make_even_bits() {
71
  bm_word_t result = 1;
72
  while (true) {
73
    bm_word_t next = (result << 2) | 1;
74
    if (next == result) {
75
      return result;
76
    }
77
    result = next;
78
  }
79
}
80

81
const bm_word_t even_bits = make_even_bits();
82
const bm_word_t odd_bits = ~even_bits;
83
const bm_word_t one_bits = ~bm_word_t(0);
84
const bm_word_t zero_bits = 0;
85

86
// Scoped set a clear bit and restore to clear.
87
class WithBitSet {
88
private:
89
  BitMap& _bm;
90
  idx_t _index;
91

92
public:
93
  WithBitSet(BitMap& bm, idx_t index) : _bm(bm), _index(index) {
94
    // Failure may indicate test bug; can't use ASSERT_xxx in constructor.
95
    EXPECT_FALSE(_bm.at(_index));
96
    bm.set_bit(_index);
97
  }
98

99
  ~WithBitSet() {
100
    _bm.clear_bit(_index);
101
  }
102
};
103

104
// Scoped clear a set bit and restore to set.
105
class WithBitClear {
106
private:
107
  BitMap& _bm;
108
  idx_t _index;
109

110
public:
111
  WithBitClear(BitMap& bm, idx_t index) : _bm(bm), _index(index) {
112
    // Failure may indicate test bug; can't use ASSERT_xxx in constructor.
113
    EXPECT_TRUE(_bm.at(_index));
114
    bm.clear_bit(_index);
115
  }
116

117
  ~WithBitClear() {
118
    _bm.set_bit(_index);
119
  }
120
};
121

122
//////////////////////////////////////////////////////////////////////////////
123
// bool is_same(const BitMap& bits);
124

125
TEST(BitMap, is_same__aligned) {
126
  BitMapMemory mx(aligned_size);
127
  BitMapMemory my(aligned_size);
128

129
  BitMapView x = mx.make_view(aligned_size, even_bits);
130
  BitMapView y = my.make_view(aligned_size, even_bits);
131
  EXPECT_TRUE(x.is_same(y));
132

133
  WithBitClear wbc(x, aligned_size / 2);
134
  EXPECT_FALSE(x.is_same(y));
135
}
136

137
TEST(BitMap, is_same__unaligned) {
138
  BitMapMemory mx(aligned_size);
139
  BitMapMemory my(aligned_size);
140

141
  BitMapView x = mx.make_view(unaligned_size, even_bits);
142
  BitMapView y = my.make_view(unaligned_size, even_bits);
143

144
  // Check that a difference beyond the end of x/y doesn't count.
145
  {
146
    BitMapView aligned = BitMapView(mx.memory(), aligned_size);
147
    const idx_t index = aligned_size - 2;
148
    STATIC_ASSERT(unaligned_size <= index);
149

150
    WithBitClear wbc(aligned, index);
151
    EXPECT_TRUE(x.is_same(y));
152
  }
153

154
  // Check that a difference in the final partial word does count.
155
  {
156
    idx_t index = unaligned_size - 2;
157
    ASSERT_LE(word_align_down(unaligned_size), index);
158

159
    WithBitClear wbc(y, index);
160
    EXPECT_FALSE(x.is_same(y));
161
  }
162
}
163

164
//////////////////////////////////////////////////////////////////////////////
165
// bool is_full();
166
// bool is_empty();
167

168
TEST(BitMap, is_full_or_empty__aligned) {
169
  BitMapMemory mx(aligned_size);
170

171
  {
172
    BitMapView x = mx.make_view(aligned_size, even_bits);
173
    EXPECT_FALSE(x.is_full());
174
    EXPECT_FALSE(x.is_empty());
175
  }
176

177
  {
178
    BitMapView x = mx.make_view(aligned_size, zero_bits);
179
    EXPECT_FALSE(x.is_full());
180
    EXPECT_TRUE(x.is_empty());
181
  }
182

183
  {
184
    BitMapView x = mx.make_view(aligned_size, one_bits);
185
    EXPECT_TRUE(x.is_full());
186
    EXPECT_FALSE(x.is_empty());
187
  }
188
}
189

190
TEST(BitMap, is_full__unaligned) {
191
  BitMapMemory mx(aligned_size);
192

193
  BitMapView x = mx.make_view(unaligned_size, one_bits);
194
  EXPECT_TRUE(x.is_full());
195

196
  // Check that a missing bit beyond the end doesn't count.
197
  {
198
    idx_t index = aligned_size - 1;
199
    BitMapView aligned = BitMapView(mx.memory(), aligned_size);
200

201
    WithBitClear wcb(aligned, index);
202
    EXPECT_FALSE(aligned.is_full());
203
    EXPECT_TRUE(x.is_full());
204
  }
205

206
  // Check that a missing bit in the final partial word does count.
207
  {
208
    WithBitClear wcb(x, unaligned_size - 1);
209
    EXPECT_FALSE(x.is_full());
210
  }
211
}
212

213
TEST(BitMap, is_empty__unaligned) {
214
  BitMapMemory mx(aligned_size);
215

216
  BitMapView x = mx.make_view(unaligned_size, zero_bits);
217
  EXPECT_TRUE(x.is_empty());
218

219
  // Check that a set bit beyond the end doesn't count.
220
  {
221
    idx_t index = aligned_size - 1;
222
    BitMapView aligned = BitMapView(mx.memory(), aligned_size);
223

224
    WithBitSet wbs(aligned, index);
225
    EXPECT_FALSE(aligned.is_empty());
226
    EXPECT_TRUE(x.is_empty());
227
  }
228

229
  // Check that a set bit in the final partial word does count.
230
  {
231
    WithBitSet wbs(x, unaligned_size - 1);
232
    EXPECT_FALSE(x.is_empty());
233
  }
234
}
235

236
//////////////////////////////////////////////////////////////////////////////
237
// bool contains(const BitMap& bits);
238

239
TEST(BitMap, contains__aligned) {
240
  BitMapMemory mx(aligned_size);
241
  BitMapMemory my(aligned_size);
242

243
  BitMapView x = mx.make_view(aligned_size, even_bits);
244
  BitMapView y = my.make_view(aligned_size, even_bits);
245
  EXPECT_TRUE(x.contains(y));
246

247
  WithBitClear wbc(x, aligned_size / 2);
248
  EXPECT_FALSE(x.contains(y));
249
}
250

251
TEST(BitMap, contains__unaligned) {
252
  BitMapMemory mx(aligned_size);
253
  BitMapMemory my(aligned_size);
254

255
  BitMapView x = mx.make_view(unaligned_size, even_bits);
256
  BitMapView y = my.make_view(unaligned_size, even_bits);
257

258
  // Check that a missing bit beyond the end of x doesn't count.
259
  {
260
    BitMapView aligned = BitMapView(mx.memory(), aligned_size);
261
    const idx_t index = aligned_size - 2;
262
    STATIC_ASSERT(unaligned_size <= index);
263

264
    WithBitClear wbc(aligned, index);
265
    EXPECT_TRUE(x.contains(y));
266
  }
267

268
  // Check that a missing bit in the final partial word does count.
269
  {
270
    idx_t index = unaligned_size - 2;
271
    ASSERT_LE(word_align_down(unaligned_size), index);
272

273
    WithBitClear wbc(x, index);
274
    EXPECT_FALSE(x.contains(y));
275
  }
276
}
277

278
//////////////////////////////////////////////////////////////////////////////
279
// bool intersects(const BitMap& bits);
280

281
TEST(BitMap, intersects__aligned) {
282
  BitMapMemory mx(aligned_size);
283
  BitMapMemory my(aligned_size);
284

285
  BitMapView x = mx.make_view(aligned_size, even_bits);
286
  BitMapView y = my.make_view(aligned_size, zero_bits);
287
  EXPECT_FALSE(x.intersects(y));
288

289
  ASSERT_TRUE(x.at(aligned_size / 2));
290
  WithBitSet wbs(y, aligned_size / 2);
291
  EXPECT_TRUE(x.intersects(y));
292
}
293

294
TEST(BitMap, intersects__unaligned) {
295
  BitMapMemory mx(aligned_size);
296
  BitMapMemory my(aligned_size);
297

298
  BitMapView x = mx.make_view(unaligned_size, even_bits);
299
  BitMapView y = my.make_view(unaligned_size, zero_bits);
300
  EXPECT_FALSE(x.intersects(y));
301

302
  // Check that adding a bit beyond the end of y doesn't count.
303
  {
304
    BitMapView aligned_x = BitMapView(mx.memory(), aligned_size);
305
    BitMapView aligned_y = BitMapView(my.memory(), aligned_size);
306
    const idx_t index = aligned_size - 2;
307
    STATIC_ASSERT(unaligned_size <= index);
308
    ASSERT_TRUE(aligned_x.at(index));
309

310
    WithBitSet wbs(aligned_y, index);
311
    EXPECT_FALSE(x.intersects(y));
312
  }
313

314
  // Check that adding a bit in the final partial word does count.
315
  {
316
    idx_t index = unaligned_size - 2;
317
    ASSERT_LE(word_align_down(unaligned_size), index);
318
    ASSERT_TRUE(x.at(index));
319

320
    WithBitSet wbs(y, index);
321
    EXPECT_TRUE(x.intersects(y));
322
  }
323
}
324

325
//////////////////////////////////////////////////////////////////////////////
326
// void set_from(const BitMap& bits);
327
// void set_union(const BitMap& bits);
328
// void set_difference(const BitMap& bits);
329
// void set_intersection(const BitMap& bits);
330
//
331
// bool set_union_with_result(const BitMap& bits);
332
// bool set_difference_with_result(const BitMap& bits);
333
// bool set_intersection_with_result(const BitMap& bits);
334

335
static void check_tail_unmodified(BitMapMemory& mem,
336
                                  idx_t bits,
337
                                  bm_word_t fill_word) {
338
  if (!is_aligned(bits, BitsPerWord)) {
339
    idx_t last_word_bit_index = word_align_down(bits);
340
    idx_t last_word_index = BitMap::calc_size_in_words(last_word_bit_index);
341
    bm_word_t last_word = mem.memory()[last_word_index];
342
    idx_t shift = bits - last_word_bit_index;
343
    EXPECT_EQ(fill_word >> shift, last_word >> shift);
344
  }
345
}
346

347
static void check_mod_setop(void (BitMap::*f)(const BitMap&),
348
                            idx_t bits,
349
                            bm_word_t wx,
350
                            bm_word_t wy,
351
                            bm_word_t wexp) {
352
  BitMapMemory mx(bits);
353
  BitMapMemory my(bits);
354
  BitMapMemory mexp(bits);
355

356
  BitMapView x = mx.make_view(bits, wx);
357
  BitMapView y = my.make_view(bits, wy);
358
  BitMapView exp = mexp.make_view(bits, wexp);
359

360
  (x.*f)(y);
361

362
  EXPECT_TRUE(exp.is_same(x));
363
  check_tail_unmodified(mx, bits, wx);
364
}
365

366
static void check_mod_setop_with_result(bool (BitMap::*f)(const BitMap&),
367
                                        idx_t bits,
368
                                        bm_word_t wx,
369
                                        bm_word_t wy,
370
                                        bm_word_t wexp) {
371
  BitMapMemory mx(bits);
372
  BitMapMemory my(bits);
373
  BitMapMemory mexp(bits);
374

375
  BitMapView x = mx.make_view(bits, wx);
376
  BitMapView y = my.make_view(bits, wy);
377
  BitMapView exp = mexp.make_view(bits, wexp);
378

379
  bool value = (x.*f)(y);
380
  EXPECT_EQ(value, wx != wexp);
381

382
  EXPECT_TRUE(exp.is_same(x));
383
  check_tail_unmodified(mx, bits, wx);
384
}
385

386
#define CHECK_MOD_SETOP_AUX(checker, name, x, y, exp)   \
387
  TEST(BitMap, name ## __ ## x ## _ ## y) {             \
388
    checker(&BitMap::name, aligned_size,                \
389
            x ## _bits, y ## _bits, exp ## _bits);      \
390
    checker(&BitMap::name, unaligned_size,              \
391
            x ## _bits, y ## _bits, exp ## _bits);      \
392
  }
393

394
#define CHECK_MOD_SETOP(name, x, y, exp) \
395
  CHECK_MOD_SETOP_AUX(check_mod_setop, name, x, y, exp)
396

397
#define CHECK_MOD_SETOP_WITH_RESULT(name, x, y, exp) \
398
  CHECK_MOD_SETOP_AUX(check_mod_setop_with_result, name, x, y, exp)
399

400
#define CHECK_MOD_SETOPS(name, x, y, exp)                       \
401
  CHECK_MOD_SETOP(name, x, y, exp)                              \
402
  CHECK_MOD_SETOP_WITH_RESULT(name ## _with_result, x, y, exp)
403

404
CHECK_MOD_SETOP(set_from, even, even, even)
405
CHECK_MOD_SETOP(set_from, even, odd, odd)
406
CHECK_MOD_SETOP(set_from, even, one, one)
407
CHECK_MOD_SETOP(set_from, even, zero, zero)
408

409
CHECK_MOD_SETOPS(set_union, even, even, even)
410
CHECK_MOD_SETOPS(set_union, even, odd, one)
411
CHECK_MOD_SETOPS(set_union, even, one, one)
412
CHECK_MOD_SETOPS(set_union, even, zero, even)
413

414
CHECK_MOD_SETOPS(set_difference, even, even, zero)
415
CHECK_MOD_SETOPS(set_difference, even, odd, even)
416
CHECK_MOD_SETOPS(set_difference, even, one, zero)
417
CHECK_MOD_SETOPS(set_difference, even, zero, even)
418

419
CHECK_MOD_SETOPS(set_intersection, even, even, even)
420
CHECK_MOD_SETOPS(set_intersection, even, odd, zero)
421
CHECK_MOD_SETOPS(set_intersection, even, one, even)
422
CHECK_MOD_SETOPS(set_intersection, even, zero, zero)
423

424

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.