wtf/BitVector.h has a variety of bugs which manifest when the
[WebKit-https.git] / Source / JavaScriptCore / wtf / BitVector.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "BitVector.h"
28
29 #include <algorithm>
30 #include <string.h>
31 #include <wtf/Assertions.h>
32 #include <wtf/FastMalloc.h>
33 #include <wtf/StdLibExtras.h>
34
35 BitVector::BitVector(const BitVector& other)
36     : m_bitsOrPointer(makeInlineBits(0))
37 {
38     (*this) = other;
39 }
40
41 BitVector& BitVector::operator=(const BitVector& other)
42 {
43     uintptr_t newBitsOrPointer;
44     if (other.isInline())
45         newBitsOrPointer = other.m_bitsOrPointer;
46     else {
47         OutOfLineBits* newOutOfLineBits = OutOfLineBits::create(other.size());
48         memcpy(newOutOfLineBits->bits(), other.bits(), byteCount(other.size()));
49         newBitsOrPointer = bitwise_cast<uintptr_t>(newOutOfLineBits);
50     }
51     if (!isInline())
52         OutOfLineBits::destroy(outOfLineBits());
53     m_bitsOrPointer = newBitsOrPointer;
54     return *this;
55 }
56
57 void BitVector::resize(size_t numBits)
58 {
59     if (numBits <= maxInlineBits()) {
60         if (isInline())
61             return;
62     
63         OutOfLineBits* myOutOfLineBits = outOfLineBits();
64         m_bitsOrPointer = makeInlineBits(*myOutOfLineBits->bits());
65         OutOfLineBits::destroy(myOutOfLineBits);
66         return;
67     }
68     
69     resizeOutOfLine(numBits);
70 }
71
72 void BitVector::clearAll()
73 {
74     if (isInline())
75         m_bitsOrPointer = makeInlineBits(0);
76     else
77         memset(outOfLineBits()->bits(), 0, byteCount(size()));
78 }
79
80 BitVector::OutOfLineBits* BitVector::OutOfLineBits::create(size_t numBits)
81 {
82     numBits = (numBits + bitsInPointer() - 1) & ~(bitsInPointer() - 1);
83     size_t size = sizeof(OutOfLineBits) + sizeof(uintptr_t) * (numBits / bitsInPointer());
84     OutOfLineBits* result = new (fastMalloc(size)) OutOfLineBits(numBits);
85     return result;
86 }
87
88 void BitVector::OutOfLineBits::destroy(OutOfLineBits* outOfLineBits)
89 {
90     fastFree(outOfLineBits);
91 }
92
93 void BitVector::resizeOutOfLine(size_t numBits)
94 {
95     ASSERT(numBits > maxInlineBits());
96     OutOfLineBits* newOutOfLineBits = OutOfLineBits::create(numBits);
97     memcpy(newOutOfLineBits->bits(), bits(), byteCount(std::min(size(), numBits)));
98     if (!isInline())
99         OutOfLineBits::destroy(outOfLineBits());
100     m_bitsOrPointer = bitwise_cast<uintptr_t>(newOutOfLineBits);
101 }
102