/src/mozilla-central/js/src/ds/Bitmap.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 | | * vim: set ts=8 sts=4 et sw=4 tw=99: |
3 | | * This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "ds/Bitmap.h" |
8 | | |
9 | | #include <algorithm> |
10 | | |
11 | | using namespace js; |
12 | | |
13 | | SparseBitmap::~SparseBitmap() |
14 | 0 | { |
15 | 0 | for (Data::Range r(data.all()); !r.empty(); r.popFront()) |
16 | 0 | js_delete(r.front().value()); |
17 | 0 | } |
18 | | |
19 | | size_t |
20 | | SparseBitmap::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) |
21 | 0 | { |
22 | 0 | size_t size = data.shallowSizeOfExcludingThis(mallocSizeOf); |
23 | 0 | for (Data::Range r(data.all()); !r.empty(); r.popFront()) |
24 | 0 | size += mallocSizeOf(r.front().value()); |
25 | 0 | return size; |
26 | 0 | } |
27 | | |
28 | | SparseBitmap::BitBlock& |
29 | | SparseBitmap::createBlock(Data::AddPtr p, size_t blockId, AutoEnterOOMUnsafeRegion& oomUnsafe) |
30 | 4 | { |
31 | 4 | MOZ_ASSERT(!p); |
32 | 4 | BitBlock* block = js_new<BitBlock>(); |
33 | 4 | if (!block || !data.add(p, blockId, block)) |
34 | 0 | oomUnsafe.crash("Bitmap OOM"); |
35 | 4 | std::fill(block->begin(), block->end(), 0); |
36 | 4 | return *block; |
37 | 4 | } |
38 | | |
39 | | bool |
40 | | SparseBitmap::getBit(size_t bit) const |
41 | 0 | { |
42 | 0 | size_t word = bit / JS_BITS_PER_WORD; |
43 | 0 | size_t blockWord = blockStartWord(word); |
44 | 0 |
|
45 | 0 | BitBlock* block = getBlock(blockWord / WordsInBlock); |
46 | 0 | if (block) |
47 | 0 | return (*block)[word - blockWord] & (uintptr_t(1) << (bit % JS_BITS_PER_WORD)); |
48 | 0 | return false; |
49 | 0 | } |
50 | | |
51 | | void |
52 | | SparseBitmap::bitwiseAndWith(const DenseBitmap& other) |
53 | 0 | { |
54 | 0 | for (Data::Enum e(data); !e.empty(); e.popFront()) { |
55 | 0 | BitBlock& block = *e.front().value(); |
56 | 0 | size_t blockWord = e.front().key() * WordsInBlock; |
57 | 0 | bool anySet = false; |
58 | 0 | size_t numWords = wordIntersectCount(blockWord, other); |
59 | 0 | for (size_t i = 0; i < numWords; i++) { |
60 | 0 | block[i] &= other.word(blockWord + i); |
61 | 0 | anySet |= !!block[i]; |
62 | 0 | } |
63 | 0 | if (!anySet) { |
64 | 0 | js_delete(&block); |
65 | 0 | e.removeFront(); |
66 | 0 | } |
67 | 0 | } |
68 | 0 | } |
69 | | |
70 | | void |
71 | | SparseBitmap::bitwiseOrWith(const SparseBitmap& other) |
72 | 0 | { |
73 | 0 | for (Data::Range r(other.data.all()); !r.empty(); r.popFront()) { |
74 | 0 | const BitBlock& otherBlock = *r.front().value(); |
75 | 0 | BitBlock& block = getOrCreateBlock(r.front().key()); |
76 | 0 | for (size_t i = 0; i < WordsInBlock; i++) |
77 | 0 | block[i] |= otherBlock[i]; |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | | void |
82 | | SparseBitmap::bitwiseOrInto(DenseBitmap& other) const |
83 | 0 | { |
84 | 0 | for (Data::Range r(data.all()); !r.empty(); r.popFront()) { |
85 | 0 | BitBlock& block = *r.front().value(); |
86 | 0 | size_t blockWord = r.front().key() * WordsInBlock; |
87 | 0 | size_t numWords = wordIntersectCount(blockWord, other); |
88 | | #ifdef DEBUG |
89 | | // Any words out of range in other should be zero in this bitmap. |
90 | | for (size_t i = numWords; i < WordsInBlock; i++) |
91 | | MOZ_ASSERT(!block[i]); |
92 | | #endif |
93 | 0 | for (size_t i = 0; i < numWords; i++) |
94 | 0 | other.word(blockWord + i) |= block[i]; |
95 | 0 | } |
96 | 0 | } |
97 | | |
98 | | void |
99 | | SparseBitmap::bitwiseOrRangeInto(size_t wordStart, size_t numWords, uintptr_t* target) const |
100 | 0 | { |
101 | 0 | size_t blockWord = blockStartWord(wordStart); |
102 | 0 |
|
103 | 0 | // We only support using a single bit block in this API. |
104 | 0 | MOZ_ASSERT(numWords && (blockWord == blockStartWord(wordStart + numWords - 1))); |
105 | 0 |
|
106 | 0 | BitBlock* block = getBlock(blockWord / WordsInBlock); |
107 | 0 | if (block) { |
108 | 0 | for (size_t i = 0; i < numWords; i++) |
109 | 0 | target[i] |= (*block)[wordStart - blockWord + i]; |
110 | 0 | } |
111 | 0 | } |