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