Coverage Report

Created: 2018-09-25 14:53

/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
}