Modernize for loops in JSC
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGClobberSet.cpp
1 /*
2  * Copyright (C) 2013, 2014 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 "DFGClobberSet.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGClobberize.h"
32 #include "JSCInlines.h"
33 #include <wtf/ListDump.h>
34
35 namespace JSC { namespace DFG {
36
37 ClobberSet::ClobberSet() { }
38 ClobberSet::~ClobberSet() { }
39
40 void ClobberSet::add(AbstractHeap heap)
41 {
42     HashMap<AbstractHeap, bool>::AddResult result = m_clobbers.add(heap, true);
43     if (!result.isNewEntry) {
44         if (result.iterator->value)
45             return;
46         result.iterator->value = true;
47     }
48     while (heap.kind() != World) {
49         heap = heap.supertype();
50         if (!m_clobbers.add(heap, false).isNewEntry)
51             return;
52     }
53 }
54
55 void ClobberSet::addAll(const ClobberSet& other)
56 {
57     // If the other set has a direct heap, we make sure we have it and we set its
58     // value to be true.
59     //
60     // If the other heap has a super heap, we make sure it's present but don't
61     // modify its value - so we had it directly already then this doesn't change.
62     
63     if (this == &other)
64         return;
65     
66     HashMap<AbstractHeap, bool>::const_iterator iter = other.m_clobbers.begin();
67     HashMap<AbstractHeap, bool>::const_iterator end = other.m_clobbers.end();
68     for (; iter != end; ++iter)
69         m_clobbers.add(iter->key, iter->value).iterator->value |= iter->value;
70 }
71
72 bool ClobberSet::contains(AbstractHeap heap) const
73 {
74     HashMap<AbstractHeap, bool>::const_iterator iter = m_clobbers.find(heap);
75     if (iter == m_clobbers.end())
76         return false;
77     return iter->value;
78 }
79
80 bool ClobberSet::overlaps(AbstractHeap heap) const
81 {
82     if (m_clobbers.find(heap) != m_clobbers.end())
83         return true;
84     if (heap.kind() == DOMState && !heap.payload().isTop()) {
85         // DOMState heap has its own hierarchy. For direct heap clobbers that payload is not Top,
86         // we should query whether the clobber overlaps with the given heap.
87         DOMJIT::HeapRange range = DOMJIT::HeapRange::fromRaw(heap.payload().value32());
88         for (auto pair : m_clobbers) {
89             bool direct = pair.value;
90             if (!direct)
91                 continue;
92             AbstractHeap clobber = pair.key;
93             if (clobber.kind() != DOMState)
94                 continue;
95             if (clobber.payload().isTop())
96                 return true;
97             if (DOMJIT::HeapRange::fromRaw(clobber.payload().value32()).overlaps(range))
98                 return true;
99         }
100     }
101     while (heap.kind() != World) {
102         heap = heap.supertype();
103         if (contains(heap))
104             return true;
105     }
106     return false;
107 }
108
109 void ClobberSet::clear()
110 {
111     m_clobbers.clear();
112 }
113
114 HashSet<AbstractHeap> ClobberSet::direct() const
115 {
116     return setOf(true);
117 }
118
119 HashSet<AbstractHeap> ClobberSet::super() const
120 {
121     return setOf(false);
122 }
123
124 void ClobberSet::dump(PrintStream& out) const
125 {
126     out.print("(Direct:[", sortedListDump(direct()), "], Super:[", sortedListDump(super()), "])");
127 }
128
129 HashSet<AbstractHeap> ClobberSet::setOf(bool direct) const
130 {
131     HashSet<AbstractHeap> result;
132     for (auto& clobber : m_clobbers) {
133         if (clobber.value == direct)
134             result.add(clobber.key);
135     }
136     return result;
137 }
138
139 void addReads(Graph& graph, Node* node, ClobberSet& readSet)
140 {
141     ClobberSetAdd addRead(readSet);
142     NoOpClobberize noOp;
143     clobberize(graph, node, addRead, noOp, noOp);
144 }
145
146 void addWrites(Graph& graph, Node* node, ClobberSet& writeSet)
147 {
148     NoOpClobberize noOp;
149     ClobberSetAdd addWrite(writeSet);
150     clobberize(graph, node, noOp, addWrite, noOp);
151 }
152
153 void addReadsAndWrites(Graph& graph, Node* node, ClobberSet& readSet, ClobberSet& writeSet)
154 {
155     ClobberSetAdd addRead(readSet);
156     ClobberSetAdd addWrite(writeSet);
157     NoOpClobberize noOp;
158     clobberize(graph, node, addRead, addWrite, noOp);
159 }
160
161 bool readsOverlap(Graph& graph, Node* node, ClobberSet& readSet)
162 {
163     ClobberSetOverlaps addRead(readSet);
164     NoOpClobberize noOp;
165     clobberize(graph, node, addRead, noOp, noOp);
166     return addRead.result();
167 }
168
169 bool writesOverlap(Graph& graph, Node* node, ClobberSet& writeSet)
170 {
171     NoOpClobberize noOp;
172     ClobberSetOverlaps addWrite(writeSet);
173     clobberize(graph, node, noOp, addWrite, noOp);
174     return addWrite.result();
175 }
176
177 } } // namespace JSC::DFG
178
179 #endif // ENABLE(DFG_JIT)
180