2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "BitVector.h"
29 #include "wtf/LeakAnnotations.h"
30 #include "wtf/PartitionAlloc.h"
31 #include "wtf/Partitions.h"
32 #include "wtf/PrintStream.h"
38 void BitVector::setSlow(const BitVector
& other
)
40 uintptr_t newBitsOrPointer
;
42 newBitsOrPointer
= other
.m_bitsOrPointer
;
44 OutOfLineBits
* newOutOfLineBits
= OutOfLineBits::create(other
.size());
45 memcpy(newOutOfLineBits
->bits(), other
.bits(), byteCount(other
.size()));
46 newBitsOrPointer
= bitwise_cast
<uintptr_t>(newOutOfLineBits
) >> 1;
49 OutOfLineBits::destroy(outOfLineBits());
50 m_bitsOrPointer
= newBitsOrPointer
;
53 void BitVector::resize(size_t numBits
)
55 if (numBits
<= maxInlineBits()) {
59 OutOfLineBits
* myOutOfLineBits
= outOfLineBits();
60 m_bitsOrPointer
= makeInlineBits(*myOutOfLineBits
->bits());
61 OutOfLineBits::destroy(myOutOfLineBits
);
65 resizeOutOfLine(numBits
);
68 void BitVector::clearAll()
71 m_bitsOrPointer
= makeInlineBits(0);
73 memset(outOfLineBits()->bits(), 0, byteCount(size()));
76 BitVector::OutOfLineBits
* BitVector::OutOfLineBits::create(size_t numBits
)
78 // Because of the way BitVector stores the pointer, memory tools
79 // will erroneously report a leak here.
80 WTF_ANNOTATE_SCOPED_MEMORY_LEAK
;
81 numBits
= (numBits
+ bitsInPointer() - 1) & ~(bitsInPointer() - 1);
82 size_t size
= sizeof(OutOfLineBits
) + sizeof(uintptr_t) * (numBits
/ bitsInPointer());
83 void* allocation
= Partitions::bufferMalloc(size
);
84 OutOfLineBits
* result
= new (NotNull
, allocation
) OutOfLineBits(numBits
);
88 void BitVector::OutOfLineBits::destroy(OutOfLineBits
* outOfLineBits
)
90 Partitions::bufferFree(outOfLineBits
);
93 void BitVector::resizeOutOfLine(size_t numBits
)
95 ASSERT(numBits
> maxInlineBits());
96 OutOfLineBits
* newOutOfLineBits
= OutOfLineBits::create(numBits
);
97 size_t newNumWords
= newOutOfLineBits
->numWords();
99 // Make sure that all of the bits are zero in case we do a no-op resize.
100 *newOutOfLineBits
->bits() = m_bitsOrPointer
& ~(static_cast<uintptr_t>(1) << maxInlineBits());
101 memset(newOutOfLineBits
->bits() + 1, 0, (newNumWords
- 1) * sizeof(void*));
103 if (numBits
> size()) {
104 size_t oldNumWords
= outOfLineBits()->numWords();
105 memcpy(newOutOfLineBits
->bits(), outOfLineBits()->bits(), oldNumWords
* sizeof(void*));
106 memset(newOutOfLineBits
->bits() + oldNumWords
, 0, (newNumWords
- oldNumWords
) * sizeof(void*));
108 memcpy(newOutOfLineBits
->bits(), outOfLineBits()->bits(), newOutOfLineBits
->numWords() * sizeof(void*));
109 OutOfLineBits::destroy(outOfLineBits());
111 m_bitsOrPointer
= bitwise_cast
<uintptr_t>(newOutOfLineBits
) >> 1;
114 void BitVector::dump(PrintStream
& out
)
116 for (size_t i
= 0; i
< size(); ++i
) {