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