ab1741fef8f8b80cfc3bddef94100398afc0f76e
[WebKit-https.git] / Source / JavaScriptCore / heap / IsoCellSet.cpp
1 /*
2  * Copyright (C) 2017 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 "IsoCellSet.h"
28
29 #include "MarkedAllocatorInlines.h"
30 #include "MarkedBlockInlines.h"
31
32 namespace JSC {
33
34 IsoCellSet::IsoCellSet(IsoSubspace& subspace)
35     : m_subspace(subspace)
36 {
37     size_t size = subspace.m_allocator.m_blocks.size();
38     m_blocksWithBits.resize(size);
39     m_bits.grow(size);
40     subspace.m_cellSets.append(this);
41 }
42
43 IsoCellSet::~IsoCellSet()
44 {
45     if (isOnList())
46         BasicRawSentinelNode<IsoCellSet>::remove();
47 }
48
49 NEVER_INLINE Bitmap<MarkedBlock::atomsPerBlock>* IsoCellSet::addSlow(size_t blockIndex)
50 {
51     auto locker = holdLock(m_subspace.m_allocator.m_bitvectorLock);
52     auto& bitsPtrRef = m_bits[blockIndex];
53     auto* bits = bitsPtrRef.get();
54     if (!bits) {
55         bitsPtrRef = std::make_unique<Bitmap<MarkedBlock::atomsPerBlock>>();
56         bits = bitsPtrRef.get();
57         WTF::storeStoreFence();
58         m_blocksWithBits[blockIndex] = true;
59     }
60     return bits;
61 }
62
63 void IsoCellSet::didResizeBits(size_t newSize)
64 {
65     m_blocksWithBits.resize(newSize);
66     m_bits.grow(newSize);
67 }
68
69 void IsoCellSet::didRemoveBlock(size_t blockIndex)
70 {
71     {
72         auto locker = holdLock(m_subspace.m_allocator.m_bitvectorLock);
73         m_blocksWithBits[blockIndex] = false;
74     }
75     m_bits[blockIndex] = nullptr;
76 }
77
78 void IsoCellSet::sweepToFreeList(MarkedBlock::Handle* block)
79 {
80     RELEASE_ASSERT(!block->isAllocated());
81     
82     if (!m_blocksWithBits[block->index()])
83         return;
84     
85     WTF::loadLoadFence();
86     
87     if (!m_bits[block->index()]) {
88         dataLog("FATAL: for block index ", block->index(), ":\n");
89         dataLog("Blocks with bits says: ", !!m_blocksWithBits[block->index()], "\n");
90         dataLog("Bits says: ", RawPointer(m_bits[block->index()].get()), "\n");
91         RELEASE_ASSERT_NOT_REACHED();
92     }
93     
94     if (block->hasAnyNewlyAllocated()) {
95         m_bits[block->index()]->concurrentFilter(block->newlyAllocated());
96         return;
97     }
98
99     if (block->isEmpty() || block->areMarksStale()) {
100         {
101             // Holding the bitvector lock happens to be enough because that's what we also hold in
102             // other places where we manipulate this bitvector.
103             auto locker = holdLock(m_subspace.m_allocator.m_bitvectorLock);
104             m_blocksWithBits[block->index()] = false;
105         }
106         m_bits[block->index()] = nullptr;
107         return;
108     }
109     
110     m_bits[block->index()]->concurrentFilter(block->block().marks());
111 }
112
113 } // namespace JSC
114