Codemod asserts to assertxs in the runtime
[hiphop-php.git] / hphp / runtime / base / repo-auth-type-array.h
bloba783444dbc8f4f4ca8342ccec960ad90b5de6d6a
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_REPO_AUTH_TYPE_DEFS_H_
17 #define incl_HPHP_REPO_AUTH_TYPE_DEFS_H_
19 #include <cstdint>
20 #include <vector>
21 #include <type_traits>
22 #include <string>
24 #include "hphp/runtime/base/repo-auth-type.h"
25 #include "hphp/util/compact-vector.h"
27 namespace HPHP {
29 //////////////////////////////////////////////////////////////////////
32 * An array type table is a registry of known array types in a
33 * program. In RepoAuthoritative mode, with an optimized repo, it's
34 * used for assert opcodes and RepoAuthTypes for arrays.
36 * This class has the same semantics for thread safey as primitive
37 * types: multiple concurrent threads may read from this table (using
38 * the const member functions), but it is not safe to concurrently
39 * read and write.
41 struct ArrayTypeTable {
42 struct Builder;
45 * Re-populate an ArrayTypeTable using a builder object.
47 * This function invalidates array type ids for array types that
48 * weren't built with the supplied builder. The builder must not be
49 * concurrently written to while it's being used to repopulate an
50 * ArrayTypeTable.
52 void repopulate(const Builder&);
54 bool empty() const { return m_arrTypes.empty(); }
57 * Find an array type description by id.
59 const RepoAuthType::Array* lookup(uint32_t id) const {
60 assertx(id < m_arrTypes.size());
61 return m_arrTypes[id];
64 template<class SerDe>
65 typename std::enable_if<SerDe::deserializing>::type serde(SerDe&);
66 template<class SerDe>
67 typename std::enable_if<!SerDe::deserializing>::type serde(SerDe&);
69 private:
71 * Check that the ArrayTypeTable is fully resolved after deserialization.
73 bool check(const RepoAuthType::Array*) const;
75 private:
76 CompactVector<const RepoAuthType::Array*> m_arrTypes;
79 //////////////////////////////////////////////////////////////////////
82 * Global singleton instance wrapped around ArrayTypeTable. This should be
83 * only used in repo mode. Non-repo mode array type tables are stored locally in
84 * the units/unit emitters. The logic is very similar to that of LitstrTable.
86 ArrayTypeTable& globalArrayTypeTable();
88 //////////////////////////////////////////////////////////////////////
91 * Deeper information about array types are represented using this
92 * structure.
94 struct RepoAuthType::Array {
95 enum class Tag : uint8_t {
97 * Known size with zero-based contiguous integer keys.
99 * Does not currently imply kPackedKind at runtime.
101 Packed,
103 * Unknown size, zero-based contiguous integer keys.
105 * Does not currently imply kPackedKind at runtime.
107 PackedN,
109 enum class Empty : uint8_t { Maybe, No };
112 * Actually serialize or deserialize an array type.
114 * The normal blob_helper serialization of RepoAuthType::Array*'s
115 * just serializes the ids. These functions are what the
116 * ArrayTypeTable uses to (de)serialize the actual data.
118 template <class SerDe>
119 static Array* deserialize(SerDe&, const ArrayTypeTable&);
120 template <class SerDe>
121 void serialize(SerDe&) const;
123 // These are variable-sized heap allocated objects. We can't copy
124 // them around.
125 Array(const Array&) = delete;
126 Array& operator=(const Array&) = delete;
129 * Every RepoAuthType::Array in the repo has a globally unique id,
130 * which is accessible here. This is a key that can be used to find
131 * it in the ArrayTypeTable.
133 uint32_t id() const { return m_id; }
136 * In addition to the specific information about array structure,
137 * every array type has a flag for whether the array is possibly
138 * empty.
140 Empty emptiness() const { return m_emptiness; }
143 * Query which kind of array type this is.
145 * Important note: this is not the same as which runtime array kind
146 * the array will have. We may know the shape of an array without
147 * knowing whether it may have escalated or not.
149 Tag tag() const { return m_tag; }
152 * Returns: how many elements are in the array, if it is non-empty.
154 * Pre: tag() == Tag::Packed
156 uint32_t size() const {
157 assertx(tag() == Tag::Packed);
158 return m_size;
162 * Return the type of the nth element in a packed-like array.
164 * Pre: tag() == Tag::Packed
165 * idx < size()
167 RepoAuthType packedElem(uint32_t idx) const {
168 assertx(tag() == Tag::Packed);
169 assertx(idx < size());
170 return types()[idx];
174 * Return a type that is larger than all possible element types.
176 * Pre: tag() == Tag::PackedN
178 RepoAuthType elemType() const {
179 assertx(tag() == Tag::PackedN);
180 return types()[0];
183 private:
184 Array(Tag tag, Empty emptiness, uint32_t size)
185 : m_tag(tag)
186 , m_emptiness(emptiness)
187 , m_id(-1u)
188 , m_size(size)
190 ~Array() {}
192 RepoAuthType* types() {
193 return reinterpret_cast<RepoAuthType*>(this + 1);
195 const RepoAuthType* types() const {
196 return reinterpret_cast<const RepoAuthType*>(this + 1);
199 private:
200 friend struct ArrayTypeTable;
201 friend struct ArrayTypeTable::Builder;
203 private:
204 Tag m_tag;
205 Empty m_emptiness;
206 uint32_t m_id;
207 uint32_t m_size;
210 //////////////////////////////////////////////////////////////////////
213 * Creating an ArrayTypeTable (during repo-building time) is done
214 * using this builder object.
216 * During normal program operation the set of types in the array type
217 * table is fixed, and there's no need to do any locking. However
218 * when it's being build (in hhbbc) it's creating them in parallel,
219 * and probably will lots of duplicate types. This object handles
220 * coalescing the duplicates and packing them into a format usable for
221 * the actual table.
223 * Instances of this class may be concurrently accessed for any
224 * routines except move-construction and move assignment, or while it
225 * is being used in a call to ArrayTypeTable::repopulate.
227 struct ArrayTypeTable::Builder {
228 Builder();
229 Builder(const Builder&) = delete;
230 Builder& operator=(const Builder&) = delete;
231 ~Builder();
234 * Create a new Packed array type descriptor, using this table
235 * builder. May return an existing descriptor if it has the same
236 * shape as an array type that already exists.
238 * Pre: !types.empty()
240 const RepoAuthType::Array* packed(
241 RepoAuthType::Array::Empty emptiness,
242 const std::vector<RepoAuthType>& types);
245 * Create a new PackedN array type descriptor, using this table
246 * builder. May return an existing descriptor if it has the same
247 * shape as a PackedN type that already exists.
249 const RepoAuthType::Array* packedn(RepoAuthType::Array::Empty emptiness,
250 RepoAuthType elemTy);
252 private:
253 const RepoAuthType::Array* insert(RepoAuthType::Array*);
255 private:
256 friend struct ArrayTypeTable;
257 struct Impl;
258 std::unique_ptr<Impl> m_impl;
261 //////////////////////////////////////////////////////////////////////
264 * Create a readable string for this type.
266 * This string is also in a parsable format used for the assembler.
268 std::string show(const RepoAuthType::Array&);
270 //////////////////////////////////////////////////////////////////////
274 #include "hphp/runtime/base/repo-auth-type-array-inl.h"
276 #endif