12867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
22867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Copyright (C) 2008 The Android Open Source Project
32867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden *
42867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
52867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * you may not use this file except in compliance with the License.
62867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * You may obtain a copy of the License at
72867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden *
82867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
92867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden *
102867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Unless required by applicable law or agreed to in writing, software
112867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
122867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * See the License for the specific language governing permissions and
142867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * limitations under the License.
152867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
162867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
172867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
182867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Implementation of an expandable bit vector.
192867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
202867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden#include "Dalvik.h"
212867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
222867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden#include <stdlib.h>
23552cacb8aef667fec06196e6d33d2d81177a61fbCarl Shapiro#include <strings.h>
242867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
252867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden#define kBitVectorGrowth    4   /* increase by 4 u4s when limit hit */
262867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
272867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
282867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
292867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Allocate a bit vector with enough space to hold at least the specified
302867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * number of bits.
312867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenBitVector* dvmAllocBitVector(unsigned int startBits, bool expandable)
332867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
342867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    BitVector* bv;
359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int count;
362867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
372867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    assert(sizeof(bv->storage[0]) == 4);        /* assuming 32-bit units */
382867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
392867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    bv = (BitVector*) malloc(sizeof(BitVector));
402867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
412867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    count = (startBits + 31) >> 5;
422867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
432867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    bv->storageSize = count;
442867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    bv->expandable = expandable;
45b74e7190e86d559712747e5cdb31a0d390b7af7dIliyan Malchev    bv->storage = (u4*) calloc(count, sizeof(u4));
462867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    return bv;
472867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
482867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
492867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
502867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Free a BitVector.
512867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
522867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenvoid dvmFreeBitVector(BitVector* pBits)
532867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
542867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    if (pBits == NULL)
552867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        return;
562867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
572867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    free(pBits->storage);
582867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    free(pBits);
592867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
602867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
612867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
622867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * "Allocate" the first-available bit in the bitmap.
632867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden *
642867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * This is not synchronized.  The caller is expected to hold some sort of
652867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * lock that prevents multiple threads from executing simultaneously in
662867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * dvmAllocBit/dvmFreeBit.
672867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
682867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenint dvmAllocBit(BitVector* pBits)
692867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int word, bit;
712867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
722867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenretry:
732867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    for (word = 0; word < pBits->storageSize; word++) {
742867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        if (pBits->storage[word] != 0xffffffff) {
752867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            /*
762867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden             * There are unallocated bits in this word.  Return the first.
772867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden             */
782867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            bit = ffs(~(pBits->storage[word])) -1;
799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            assert(bit < 32);
802867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            pBits->storage[word] |= 1 << bit;
812867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            return (word << 5) | bit;
822867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        }
832867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    }
842867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
852867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    /*
862867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden     * Ran out of space, allocate more if we're allowed to.
872867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden     */
882867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    if (!pBits->expandable)
892867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        return -1;
902867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
912867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    pBits->storage = (u4*)realloc(pBits->storage,
922867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                    (pBits->storageSize + kBitVectorGrowth) * sizeof(u4));
932867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    memset(&pBits->storage[pBits->storageSize], 0x00,
942867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        kBitVectorGrowth * sizeof(u4));
952867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    pBits->storageSize += kBitVectorGrowth;
962867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    goto retry;
972867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
982867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
992867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
1002867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Mark the specified bit as "set".
1012867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
1029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenvoid dvmSetBit(BitVector* pBits, unsigned int num)
1032867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
1049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (num >= pBits->storageSize * sizeof(u4) * 8) {
1059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (!pBits->expandable) {
106c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block            ALOGE("Attempt to set bit outside valid range (%d, limit is %d)",
1079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                num, pBits->storageSize * sizeof(u4) * 8);
1089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dvmAbort();
1099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1102867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1112867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        /* Round up to word boundaries for "num+1" bits */
1129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        unsigned int newSize = (num + 1 + 31) >> 5;
1132867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        assert(newSize > pBits->storageSize);
1142867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        pBits->storage = (u4*)realloc(pBits->storage, newSize * sizeof(u4));
1159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (pBits->storage == NULL) {
116c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block            ALOGE("BitVector expansion to %d failed", newSize * sizeof(u4));
1179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dvmAbort();
1189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1192867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        memset(&pBits->storage[pBits->storageSize], 0x00,
1202867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            (newSize - pBits->storageSize) * sizeof(u4));
1212867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        pBits->storageSize = newSize;
1222867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    }
1232867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1242867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    pBits->storage[num >> 5] |= 1 << (num & 0x1f);
1252867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
1262867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1272867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
1282867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Mark the specified bit as "clear".
1292867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
1309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenvoid dvmClearBit(BitVector* pBits, unsigned int num)
1312867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
1329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    assert(num < pBits->storageSize * sizeof(u4) * 8);
1332867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1342867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    pBits->storage[num >> 5] &= ~(1 << (num & 0x1f));
1352867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
1362867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1372867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
1382867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Mark all bits bit as "clear".
1392867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
1402867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenvoid dvmClearAllBits(BitVector* pBits)
1412867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
1429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int count = pBits->storageSize;
1432867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    memset(pBits->storage, 0, count * sizeof(u4));
1442867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
1452867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1462867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
14700603079b8723b32c955513eae63a8f97898074dBen Cheng * Mark specified number of bits as "set". Cannot set all bits like ClearAll
14800603079b8723b32c955513eae63a8f97898074dBen Cheng * since there might be unused bits - setting those to one will confuse the
14900603079b8723b32c955513eae63a8f97898074dBen Cheng * iterator.
15000603079b8723b32c955513eae63a8f97898074dBen Cheng */
1519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenvoid dvmSetInitialBits(BitVector* pBits, unsigned int numBits)
15200603079b8723b32c955513eae63a8f97898074dBen Cheng{
1539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
15400603079b8723b32c955513eae63a8f97898074dBen Cheng    assert(((numBits + 31) >> 5) <= pBits->storageSize);
1559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < (numBits >> 5); idx++) {
1569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        pBits->storage[idx] = -1;
15700603079b8723b32c955513eae63a8f97898074dBen Cheng    }
1589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int remNumBits = numBits & 0x1f;
15900603079b8723b32c955513eae63a8f97898074dBen Cheng    if (remNumBits) {
1609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        pBits->storage[idx] = (1 << remNumBits) - 1;
16100603079b8723b32c955513eae63a8f97898074dBen Cheng    }
16200603079b8723b32c955513eae63a8f97898074dBen Cheng}
16300603079b8723b32c955513eae63a8f97898074dBen Cheng
16400603079b8723b32c955513eae63a8f97898074dBen Cheng/*
1652867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Determine whether or not the specified bit is set.
1662867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
1679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenbool dvmIsBitSet(const BitVector* pBits, unsigned int num)
1682867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
1699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    assert(num < pBits->storageSize * sizeof(u4) * 8);
1702867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int val = pBits->storage[num >> 5] & (1 << (num & 0x1f));
1722867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    return (val != 0);
1732867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
1742867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1752867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
1762867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Count the number of bits that are set.
1772867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
1782867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenint dvmCountSetBits(const BitVector* pBits)
1792867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
1809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int word;
1819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int count = 0;
1822867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1832867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    for (word = 0; word < pBits->storageSize; word++) {
1842867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        u4 val = pBits->storage[word];
1852867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1862867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        if (val != 0) {
1872867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            if (val == 0xffffffff) {
1882867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                count += 32;
1892867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            } else {
1902867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                /* count the number of '1' bits */
1912867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                while (val != 0) {
1922867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                    val &= val - 1;
1932867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                    count++;
1942867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                }
1952867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden            }
1962867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        }
1972867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    }
1982867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
1992867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    return count;
2002867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
2012867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
2022867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
2039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * If the vector sizes don't match, log an error and abort.
2049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
2059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic void checkSizes(const BitVector* bv1, const BitVector* bv2)
2069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
2079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (bv1->storageSize != bv2->storageSize) {
208c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block        ALOGE("Mismatched vector sizes (%d, %d)",
2099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            bv1->storageSize, bv2->storageSize);
2109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        dvmAbort();
2119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
2129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
2139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
2152867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden * Copy a whole vector to the other. Only do that when the both vectors have
2169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * the same size.
2172867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
2189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenvoid dvmCopyBitVector(BitVector *dest, const BitVector *src)
2192867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
2209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /* if dest is expandable and < src, we could expand dest to match */
2219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    checkSizes(dest, src);
2229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2232867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
2242867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
2252867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
2262867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden/*
22700603079b8723b32c955513eae63a8f97898074dBen Cheng * Intersect two bit vectors and store the result to the dest vector.
2282867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden */
2292867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFaddenbool dvmIntersectBitVectors(BitVector *dest, const BitVector *src1,
2302867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden                            const BitVector *src2)
2312867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden{
2322867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    if (dest->storageSize != src1->storageSize ||
2332867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        dest->storageSize != src2->storageSize ||
2342867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        dest->expandable != src1->expandable ||
2352867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        dest->expandable != src2->expandable)
2362867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden        return false;
2372867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden
2389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
2399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < dest->storageSize; idx++) {
2409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
2412867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    }
2422867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden    return true;
2432867f0b3f48d3dcbdba9b4ba7db27f6107313663Andy McFadden}
24400603079b8723b32c955513eae63a8f97898074dBen Cheng
24500603079b8723b32c955513eae63a8f97898074dBen Cheng/*
24600603079b8723b32c955513eae63a8f97898074dBen Cheng * Unify two bit vectors and store the result to the dest vector.
24700603079b8723b32c955513eae63a8f97898074dBen Cheng */
24800603079b8723b32c955513eae63a8f97898074dBen Chengbool dvmUnifyBitVectors(BitVector *dest, const BitVector *src1,
24900603079b8723b32c955513eae63a8f97898074dBen Cheng                        const BitVector *src2)
25000603079b8723b32c955513eae63a8f97898074dBen Cheng{
25100603079b8723b32c955513eae63a8f97898074dBen Cheng    if (dest->storageSize != src1->storageSize ||
25200603079b8723b32c955513eae63a8f97898074dBen Cheng        dest->storageSize != src2->storageSize ||
25300603079b8723b32c955513eae63a8f97898074dBen Cheng        dest->expandable != src1->expandable ||
25400603079b8723b32c955513eae63a8f97898074dBen Cheng        dest->expandable != src2->expandable)
25500603079b8723b32c955513eae63a8f97898074dBen Cheng        return false;
25600603079b8723b32c955513eae63a8f97898074dBen Cheng
2579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
2589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < dest->storageSize; idx++) {
2599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
26000603079b8723b32c955513eae63a8f97898074dBen Cheng    }
26100603079b8723b32c955513eae63a8f97898074dBen Cheng    return true;
26200603079b8723b32c955513eae63a8f97898074dBen Cheng}
26300603079b8723b32c955513eae63a8f97898074dBen Cheng
26400603079b8723b32c955513eae63a8f97898074dBen Cheng/*
26500603079b8723b32c955513eae63a8f97898074dBen Cheng * Compare two bit vectors and return true if difference is seen.
26600603079b8723b32c955513eae63a8f97898074dBen Cheng */
26700603079b8723b32c955513eae63a8f97898074dBen Chengbool dvmCompareBitVectors(const BitVector *src1, const BitVector *src2)
26800603079b8723b32c955513eae63a8f97898074dBen Cheng{
26900603079b8723b32c955513eae63a8f97898074dBen Cheng    if (src1->storageSize != src2->storageSize ||
27000603079b8723b32c955513eae63a8f97898074dBen Cheng        src1->expandable != src2->expandable)
27100603079b8723b32c955513eae63a8f97898074dBen Cheng        return true;
27200603079b8723b32c955513eae63a8f97898074dBen Cheng
2739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
2749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < src1->storageSize; idx++) {
2759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (src1->storage[idx] != src2->storage[idx]) return true;
27600603079b8723b32c955513eae63a8f97898074dBen Cheng    }
27700603079b8723b32c955513eae63a8f97898074dBen Cheng    return false;
27800603079b8723b32c955513eae63a8f97898074dBen Cheng}
27900603079b8723b32c955513eae63a8f97898074dBen Cheng
28000603079b8723b32c955513eae63a8f97898074dBen Cheng/* Initialize the iterator structure */
28100603079b8723b32c955513eae63a8f97898074dBen Chengvoid dvmBitVectorIteratorInit(BitVector* pBits, BitVectorIterator* iterator)
28200603079b8723b32c955513eae63a8f97898074dBen Cheng{
28300603079b8723b32c955513eae63a8f97898074dBen Cheng    iterator->pBits = pBits;
28400603079b8723b32c955513eae63a8f97898074dBen Cheng    iterator->bitSize = pBits->storageSize * sizeof(u4) * 8;
28500603079b8723b32c955513eae63a8f97898074dBen Cheng    iterator->idx = 0;
28600603079b8723b32c955513eae63a8f97898074dBen Cheng}
28700603079b8723b32c955513eae63a8f97898074dBen Cheng
28800603079b8723b32c955513eae63a8f97898074dBen Cheng/* Return the next position set to 1. -1 means end-of-element reached */
28900603079b8723b32c955513eae63a8f97898074dBen Chengint dvmBitVectorIteratorNext(BitVectorIterator* iterator)
29000603079b8723b32c955513eae63a8f97898074dBen Cheng{
29100603079b8723b32c955513eae63a8f97898074dBen Cheng    const BitVector* pBits = iterator->pBits;
29200603079b8723b32c955513eae63a8f97898074dBen Cheng    u4 bitIndex = iterator->idx;
29300603079b8723b32c955513eae63a8f97898074dBen Cheng
29400603079b8723b32c955513eae63a8f97898074dBen Cheng    assert(iterator->bitSize == pBits->storageSize * sizeof(u4) * 8);
29500603079b8723b32c955513eae63a8f97898074dBen Cheng    if (bitIndex >= iterator->bitSize) return -1;
29600603079b8723b32c955513eae63a8f97898074dBen Cheng
29700603079b8723b32c955513eae63a8f97898074dBen Cheng    for (; bitIndex < iterator->bitSize; bitIndex++) {
2989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        unsigned int wordIndex = bitIndex >> 5;
2999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        unsigned int mask = 1 << (bitIndex & 0x1f);
30000603079b8723b32c955513eae63a8f97898074dBen Cheng        if (pBits->storage[wordIndex] & mask) {
30100603079b8723b32c955513eae63a8f97898074dBen Cheng            iterator->idx = bitIndex+1;
30200603079b8723b32c955513eae63a8f97898074dBen Cheng            return bitIndex;
30300603079b8723b32c955513eae63a8f97898074dBen Cheng        }
30400603079b8723b32c955513eae63a8f97898074dBen Cheng    }
30500603079b8723b32c955513eae63a8f97898074dBen Cheng    /* No more set bits */
30600603079b8723b32c955513eae63a8f97898074dBen Cheng    return -1;
30700603079b8723b32c955513eae63a8f97898074dBen Cheng}
3089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
3119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Merge the contents of "src" into "dst", checking to see if this causes
3129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * any changes to occur.  This is a logical OR.
3139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
3149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Returns "true" if the contents of the destination vector were modified.
3159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
3169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenbool dvmCheckMergeBitVectors(BitVector* dst, const BitVector* src)
3179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
3189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    bool changed = false;
3199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    checkSizes(dst, src);
3219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
3239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < dst->storageSize; idx++) {
3249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        u4 merged = src->storage[idx] | dst->storage[idx];
3259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (dst->storage[idx] != merged) {
3269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dst->storage[idx] = merged;
3279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            changed = true;
3289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
3299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
3309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return changed;
3329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
333