1/*
2 * Copyright (C) 2015-2016 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#if ENABLE(B3_JIT)
29
30namespace JSC { namespace B3 {
31
32// This is a generic wrapper around lists of frequented blocks, which gives you just the blocks.
33
34template<typename BasicBlock, typename SuccessorList>
35class SuccessorCollection {
36public:
37 SuccessorCollection(SuccessorList& list)
38 : m_list(list)
39 {
40 }
41
42 size_t size() const { return m_list.size(); }
43 BasicBlock* at(size_t index) const { return m_list[index].block(); }
44 BasicBlock*& at(size_t index) { return m_list[index].block(); }
45 BasicBlock* operator[](size_t index) const { return at(index); }
46 BasicBlock*& operator[](size_t index) { return at(index); }
47
48 class iterator {
49 public:
50 iterator()
51 : m_collection(nullptr)
52 , m_index(0)
53 {
54 }
55
56 iterator(SuccessorCollection& collection, size_t index)
57 : m_collection(&collection)
58 , m_index(index)
59 {
60 }
61
62 BasicBlock*& operator*() const
63 {
64 return m_collection->at(m_index);
65 }
66
67 iterator& operator++()
68 {
69 m_index++;
70 return *this;
71 }
72
73 bool operator==(const iterator& other) const
74 {
75 ASSERT(m_collection == other.m_collection);
76 return m_index == other.m_index;
77 }
78
79 bool operator!=(const iterator& other) const
80 {
81 return !(*this == other);
82 }
83
84 private:
85 SuccessorCollection* m_collection;
86 size_t m_index;
87 };
88
89 iterator begin() { return iterator(*this, 0); }
90 iterator end() { return iterator(*this, size()); }
91
92 class const_iterator {
93 public:
94 const_iterator()
95 : m_collection(nullptr)
96 , m_index(0)
97 {
98 }
99
100 const_iterator(const SuccessorCollection& collection, size_t index)
101 : m_collection(&collection)
102 , m_index(index)
103 {
104 }
105
106 BasicBlock* operator*() const
107 {
108 return m_collection->at(m_index);
109 }
110
111 const_iterator& operator++()
112 {
113 m_index++;
114 return *this;
115 }
116
117 bool operator==(const const_iterator& other) const
118 {
119 ASSERT(m_collection == other.m_collection);
120 return m_index == other.m_index;
121 }
122
123 bool operator!=(const const_iterator& other) const
124 {
125 return !(*this == other);
126 }
127
128 private:
129 const SuccessorCollection* m_collection;
130 size_t m_index;
131 };
132
133 const_iterator begin() const { return const_iterator(*this, 0); }
134 const_iterator end() const { return const_iterator(*this, size()); }
135
136private:
137 SuccessorList& m_list;
138};
139
140} } // namespace JSC::B3
141
142#endif // ENABLE(B3_JIT)
143