2 +----------------------------------------------------------------------+
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_
21 #include <type_traits>
24 #include "hphp/runtime/base/repo-auth-type.h"
25 #include "hphp/util/compact-vector.h"
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
41 struct ArrayTypeTable
{
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
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
];
65 typename
std::enable_if
<SerDe::deserializing
>::type
serde(SerDe
&);
67 typename
std::enable_if
<!SerDe::deserializing
>::type
serde(SerDe
&);
71 * Check that the ArrayTypeTable is fully resolved after deserialization.
73 bool check(const RepoAuthType::Array
*) const;
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
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.
103 * Unknown size, zero-based contiguous integer keys.
105 * Does not currently imply kPackedKind at runtime.
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
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
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
);
162 * Return the type of the nth element in a packed-like array.
164 * Pre: tag() == Tag::Packed
167 RepoAuthType
packedElem(uint32_t idx
) const {
168 assertx(tag() == Tag::Packed
);
169 assertx(idx
< size());
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
);
184 Array(Tag tag
, Empty emptiness
, uint32_t size
)
186 , m_emptiness(emptiness
)
192 RepoAuthType
* types() {
193 return reinterpret_cast<RepoAuthType
*>(this + 1);
195 const RepoAuthType
* types() const {
196 return reinterpret_cast<const RepoAuthType
*>(this + 1);
200 friend struct ArrayTypeTable
;
201 friend struct ArrayTypeTable::Builder
;
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
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
{
229 Builder(const Builder
&) = delete;
230 Builder
& operator=(const Builder
&) = delete;
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
);
253 const RepoAuthType::Array
* insert(RepoAuthType::Array
*);
256 friend struct ArrayTypeTable
;
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"