LCOV - code coverage report
Current view: top level - js/src/ds - Bitmap.h (source / functions) Hit Total Coverage
Test: output.info Lines: 18 36 50.0 %
Date: 2017-07-14 16:53:18 Functions: 6 15 40.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef ds_Bitmap_h
       8             : #define ds_Bitmap_h
       9             : 
      10             : #include <algorithm>
      11             : 
      12             : #include "jsalloc.h"
      13             : 
      14             : #include "js/HashTable.h"
      15             : #include "js/Vector.h"
      16             : 
      17             : // This file provides two classes for representing bitmaps.
      18             : //
      19             : // DenseBitmap is an array of words of bits, with size linear in the maximum
      20             : // bit which has been set on it.
      21             : //
      22             : // SparseBitmap provides a reasonably simple, reasonably efficient (in time and
      23             : // space) implementation of a sparse bitmap. The basic representation is a hash
      24             : // table whose entries are fixed length malloc'ed blocks of bits.
      25             : 
      26             : namespace js {
      27             : 
      28           0 : class DenseBitmap
      29             : {
      30             :     typedef Vector<uintptr_t, 0, SystemAllocPolicy> Data;
      31             :     Data data;
      32             : 
      33             :   public:
      34             :     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
      35             :         return data.sizeOfExcludingThis(mallocSizeOf);
      36             :     }
      37             : 
      38           0 :     bool ensureSpace(size_t numWords) {
      39           0 :         MOZ_ASSERT(data.empty());
      40           0 :         return data.appendN(0, numWords);
      41             :     }
      42             : 
      43           0 :     size_t numWords() const { return data.length(); }
      44           0 :     uintptr_t word(size_t i) const { return data[i]; }
      45           0 :     uintptr_t& word(size_t i) { return data[i]; }
      46             : 
      47           0 :     void copyBitsFrom(size_t wordStart, size_t numWords, uintptr_t* source) {
      48           0 :         MOZ_ASSERT(wordStart + numWords <= data.length());
      49           0 :         mozilla::PodCopy(&data[wordStart], source, numWords);
      50           0 :     }
      51             : 
      52           0 :     void bitwiseOrRangeInto(size_t wordStart, size_t numWords, uintptr_t* target) const {
      53           0 :         for (size_t i = 0; i < numWords; i++)
      54           0 :             target[i] |= data[wordStart + i];
      55           0 :     }
      56             : };
      57             : 
      58          31 : class SparseBitmap
      59             : {
      60             :     // The number of words of bits to use for each block mainly affects the
      61             :     // memory usage of the bitmap. To minimize overhead, bitmaps which are
      62             :     // expected to be fairly dense should have a large block size, and bitmaps
      63             :     // which are expected to be very sparse should have a small block size.
      64             :     static const size_t WordsInBlock = 4096 / sizeof(uintptr_t);
      65             : 
      66             :     typedef mozilla::Array<uintptr_t, WordsInBlock> BitBlock;
      67             :     typedef HashMap<size_t, BitBlock*, DefaultHasher<size_t>, SystemAllocPolicy> Data;
      68             :     Data data;
      69             : 
      70      570755 :     static size_t blockStartWord(size_t word) {
      71      570755 :         return word & ~(WordsInBlock - 1);
      72             :     }
      73             : 
      74             :     // Return the number of words in a BitBlock starting at |blockWord| which
      75             :     // are in |other|.
      76           0 :     static size_t wordIntersectCount(size_t blockWord, const DenseBitmap& other) {
      77           0 :         long count = other.numWords() - blockWord;
      78           0 :         return std::min<size_t>((size_t)WordsInBlock, std::max<long>(count, 0));
      79             :     }
      80             : 
      81             :     BitBlock& createBlock(Data::AddPtr p, size_t blockId);
      82             : 
      83      368011 :     MOZ_ALWAYS_INLINE BitBlock* getBlock(size_t blockId) const {
      84      368011 :         Data::Ptr p = data.lookup(blockId);
      85      368012 :         return p ? p->value() : nullptr;
      86             :     }
      87             : 
      88      202346 :     MOZ_ALWAYS_INLINE BitBlock& getOrCreateBlock(size_t blockId) {
      89      202346 :         Data::AddPtr p = data.lookupForAdd(blockId);
      90      202347 :         if (p)
      91      202265 :             return *p->value();
      92          81 :         return createBlock(p, blockId);
      93             :     }
      94             : 
      95             :   public:
      96          31 :     bool init() { return data.init(); }
      97             :     ~SparseBitmap();
      98             : 
      99             :     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
     100             : 
     101      202304 :     MOZ_ALWAYS_INLINE void setBit(size_t bit) {
     102      202304 :         size_t word = bit / JS_BITS_PER_WORD;
     103      202304 :         size_t blockWord = blockStartWord(word);
     104      202304 :         BitBlock& block = getOrCreateBlock(blockWord / WordsInBlock);
     105      202299 :         block[word - blockWord] |= uintptr_t(1) << (bit % JS_BITS_PER_WORD);
     106      202299 :     }
     107             : 
     108             :     bool getBit(size_t bit) const;
     109             : 
     110             :     void bitwiseAndWith(const DenseBitmap& other);
     111             :     void bitwiseOrWith(const SparseBitmap& other);
     112             :     void bitwiseOrInto(DenseBitmap& other) const;
     113             : 
     114             :     // Currently, this API only supports a range of words that is in a single bit block.
     115             :     void bitwiseOrRangeInto(size_t wordStart, size_t numWords, uintptr_t* target) const;
     116             : };
     117             : 
     118             : } // namespace js
     119             : 
     120             : #endif // ds_Bitmap_h

Generated by: LCOV version 1.13