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