1/*
2 * Copyright (C) 2015 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "CodeBlock.h"
29#include <wtf/UniqueArray.h>
30
31namespace JSC {
32
33class BytecodeLivenessAnalysis;
34
35class BytecodeKills {
36 WTF_MAKE_FAST_ALLOCATED;
37public:
38 BytecodeKills()
39 : m_codeBlock(nullptr)
40 {
41 }
42
43private:
44 friend class BytecodeLivenessAnalysis;
45
46 class KillSet {
47 WTF_MAKE_FAST_ALLOCATED;
48 public:
49 KillSet()
50 : m_word(0)
51 {
52 }
53
54 ~KillSet()
55 {
56 if (hasVector())
57 delete vector();
58 }
59
60 void add(unsigned local)
61 {
62 if (isEmpty()) {
63 setOneItem(local);
64 return;
65 }
66 if (hasOneItem()) {
67 ASSERT(oneItem() != local);
68 Vector<unsigned>* vector = new Vector<unsigned>();
69 vector->append(oneItem());
70 vector->append(local);
71 setVector(vector);
72 return;
73 }
74 ASSERT(!vector()->contains(local));
75 vector()->append(local);
76 }
77
78 template<typename Functor>
79 void forEachLocal(const Functor& functor)
80 {
81 if (isEmpty())
82 return;
83 if (hasOneItem()) {
84 functor(oneItem());
85 return;
86 }
87 for (unsigned local : *vector())
88 functor(local);
89 }
90
91 bool contains(unsigned expectedLocal)
92 {
93 if (isEmpty())
94 return false;
95 if (hasOneItem())
96 return oneItem() == expectedLocal;
97 for (unsigned local : *vector()) {
98 if (local == expectedLocal)
99 return true;
100 }
101 return false;
102 }
103
104 private:
105 bool isEmpty() const
106 {
107 return !m_word;
108 }
109
110 bool hasOneItem() const
111 {
112 return m_word & 1;
113 }
114
115 unsigned oneItem() const
116 {
117 return m_word >> 1;
118 }
119
120 void setOneItem(unsigned value)
121 {
122 m_word = (value << 1) | 1;
123 }
124
125 bool hasVector() const
126 {
127 return !isEmpty() && !hasOneItem();
128 }
129
130 Vector<unsigned>* vector()
131 {
132 return bitwise_cast<Vector<unsigned>*>(m_word);
133 }
134
135 void setVector(Vector<unsigned>* value)
136 {
137 m_word = bitwise_cast<uintptr_t>(value);
138 }
139
140 uintptr_t m_word;
141 };
142
143 CodeBlock* m_codeBlock;
144 UniqueArray<KillSet> m_killSets;
145};
146
147} // namespace JSC
148