/*
* Copyright ( c ) 2020 , Oracle and / or its affiliates . All rights reserved .
* Copyright ( c ) 2020 , SAP and / or its affiliates .
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
#include "precompiled.hpp"
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/ostream.hpp"
#include "unittest.hpp"
// A simple stupid bitmap to mimic BitMap operations.
class SimpleFakeBitmap {
const int _size;
char * _buffer;
public :
SimpleFakeBitmap(int size) : _size(size), _buffer(NEW_C_HEAP_ARRAY(char , size, mtInternal)) {
clear();
}
~SimpleFakeBitmap() {
FREE_C_HEAP_ARRAY(char , _buffer);
}
// Set or clear the specified bit.
void set_range(int beg, int end) { ::memset(_buffer + beg, 'X' , end - beg); }
void clear_range(int beg, int end) { ::memset(_buffer + beg, ' ' , end - beg); }
void clear() { clear_range(0 , _size); }
bool at(int idx) const { return _buffer[idx] == 'X' ; }
unsigned popcnt(int beg, int end) const {
int sum = 0 ;
for (int i = beg; i < end; i ++) {
if (at(i)) {
sum ++;
}
}
return sum;
}
unsigned popcnt() const { return popcnt(0 , _size); }
};
#define ASSERT_POPCNT_ALL(bm, expected) \
ASSERT_EQ(bm.count_one_bits(), (BitMap::idx_t)(expected));
#define ASSERT_POPCNT_RANGE(bm, beg, end, expected) \
ASSERT_EQ(bm.count_one_bits(beg, end), (BitMap::idx_t)(expected));
#define ASSERT_POPCNT_ALL_CMP(bm, fake_bm) \
ASSERT_EQ(bm.count_one_bits(), fake_bm.popcnt());
#define ASSERT_POPCNT_RANGE_CMP(bm, beg, end, fake_bm) \
ASSERT_EQ(bm.count_one_bits(beg, end), fake_bm.popcnt(beg, end));
static void set_or_clear_random_range(BitMap& bm, SimpleFakeBitmap& fbm, int beg, int end) {
int range = end - beg;
if (range > 0 ) {
int from = os::random() % range;
int to = os::random() % range;
if (from > to) {
int s = from;
from = to;
to = s;
}
from += beg;
to += beg;
if ((os::random() % 10 ) > 5 ) {
bm.set_range(from, to);
fbm.set_range(from, to);
} else {
bm.clear_range(from, to);
fbm.clear_range(from, to);
}
}
}
static void test_bitmap_popcnt(int bitsize) {
CHeapBitMap bm(bitsize, mtTest);
SimpleFakeBitmap fbm(bitsize);
ASSERT_POPCNT_ALL(bm, 0 );
ASSERT_POPCNT_RANGE(bm, 0 , 0 , 0 );
ASSERT_POPCNT_RANGE(bm, 0 , bitsize, 0 );
const int stepsize = bitsize > 64 ? 5 : 1 ;
for (int beg = 0 ; beg < bitsize; beg += stepsize) {
for (int end = beg; end < bitsize; end += stepsize) {
bm.clear();
bm.set_range(beg, end);
fbm.clear();
fbm.set_range(beg, end);
ASSERT_POPCNT_ALL_CMP(bm, fbm);
for (int beg_query_range = 0 ; beg_query_range < bitsize; beg_query_range += stepsize) {
for (int end_query_range = beg_query_range; end_query_range < bitsize; end_query_range += stepsize) {
ASSERT_POPCNT_RANGE_CMP(bm, beg_query_range, end_query_range, fbm);
// Clear some random ranges and retest
for (int n = 0 ; n < 3 ; n ++) {
set_or_clear_random_range(bm, fbm, beg, end);
ASSERT_POPCNT_RANGE_CMP(bm, beg_query_range, end_query_range, fbm);
}
}
}
}
}
}
TEST_VM(BitMap, popcnt_1) { test_bitmap_popcnt(1 ); }
TEST_VM(BitMap, popcnt_8) { test_bitmap_popcnt(8 ); }
TEST_VM(BitMap, popcnt_15) { test_bitmap_popcnt(15 ); }
TEST_VM(BitMap, popcnt_19) { test_bitmap_popcnt(17 ); }
TEST_VM(BitMap, popcnt_63) { test_bitmap_popcnt(63 ); }
TEST_VM(BitMap, popcnt_300) { test_bitmap_popcnt(300 ); }
TEST_VM(BitMap, popcnt_large) {
CHeapBitMap bm(64 * K, mtTest);
ASSERT_POPCNT_ALL(bm, 0 );
ASSERT_POPCNT_RANGE(bm, 0 , 64 * K, 0 );
ASSERT_POPCNT_RANGE(bm, 47 , 199 , 0 );
bm.set_bit(100 );
ASSERT_POPCNT_ALL(bm, 1 );
ASSERT_POPCNT_RANGE(bm, 0 , 64 * K, 1 );
ASSERT_POPCNT_RANGE(bm, 47 , 199 , 1 );
ASSERT_POPCNT_RANGE(bm, 199 , 299 , 0 );
bm.set_range(0 , 64 * K);
ASSERT_POPCNT_ALL(bm, 64 * K);
ASSERT_POPCNT_RANGE(bm, 0 , 64 * K, 64 * K);
ASSERT_POPCNT_RANGE(bm, 47 , 199 , 152 );
ASSERT_POPCNT_RANGE(bm, 199 , 299 , 100 );
}
Messung V0.5 in Prozent C=98 H=80 G=89
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland