Unreviewed, rolling out r206522.
[WebKit.git] / Source / JavaScriptCore / heap / GCIncomingRefCountedInlines.h
1 /*
2  * Copyright (C) 2013 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 #pragma once
27
28 #include "GCIncomingRefCounted.h"
29 #include "Heap.h"
30
31 namespace JSC {
32
33 template<typename T>
34 bool GCIncomingRefCounted<T>::addIncomingReference(JSCell* cell)
35 {
36     if (!hasAnyIncoming()) {
37         m_encodedPointer = bitwise_cast<uintptr_t>(cell) | singletonFlag();
38         this->setIsDeferred(true);
39         ASSERT(hasSingleton());
40         return true;
41     }
42     
43     ASSERT(Heap::heap(incomingReferenceAt(0)) == Heap::heap(cell));
44     
45     if (hasSingleton()) {
46         Vector<JSCell*>* vector = new Vector<JSCell*>();
47         vector->append(singleton());
48         vector->append(cell);
49         m_encodedPointer = bitwise_cast<uintptr_t>(vector);
50         ASSERT(hasVectorOfCells());
51         return false;
52     }
53     
54     vectorOfCells()->append(cell);
55     return false;
56 }
57
58 template<typename T>
59 template<typename FilterFunctionType>
60 bool GCIncomingRefCounted<T>::filterIncomingReferences(FilterFunctionType& filterFunction)
61 {
62     const bool verbose = false;
63     
64     if (verbose)
65         dataLog("Filtering incoming references.\n");
66     
67     if (!hasAnyIncoming()) {
68         ASSERT(!this->isDeferred());
69         ASSERT(this->refCount());
70         if (verbose)
71             dataLog("    Has no incoming.\n");
72         return false;
73     }
74     
75     ASSERT(this->isDeferred());
76     
77     if (hasSingleton()) {
78         if (filterFunction(singleton())) {
79             if (verbose)
80                 dataLog("   Singleton passed.\n");
81             return false;
82         }
83         
84         if (verbose)
85             dataLog("   Removing singleton.\n");
86         m_encodedPointer = 0;
87         ASSERT(!hasAnyIncoming());
88         this->setIsDeferred(false);
89         return true;
90     }
91     
92     if (verbose)
93         dataLog("   Has ", vectorOfCells()->size(), " entries.\n");
94     for (size_t i = 0; i < vectorOfCells()->size(); ++i) {
95         if (filterFunction(vectorOfCells()->at(i)))
96             continue;
97         vectorOfCells()->at(i--) = vectorOfCells()->last();
98         vectorOfCells()->removeLast();
99     }
100     
101     if (vectorOfCells()->size() >= 2) {
102         if (verbose)
103             dataLog("   Still has ", vectorOfCells()->size(), " entries.\n");
104         return false;
105     }
106     
107     if (vectorOfCells()->isEmpty()) {
108         if (verbose)
109             dataLog("   Removing.\n");
110         delete vectorOfCells();
111         m_encodedPointer = 0;
112         ASSERT(!hasAnyIncoming());
113         this->setIsDeferred(false);
114         return true;
115     }
116     
117     if (verbose)
118         dataLog("   Shrinking to singleton.\n");
119     JSCell* singleton = vectorOfCells()->at(0);
120     delete vectorOfCells();
121     m_encodedPointer = bitwise_cast<uintptr_t>(singleton) | singletonFlag();
122     ASSERT(hasSingleton());
123     return false;
124 }
125
126 } // namespace JSC