ban traits that defines properties inherited via multiple paths if <<__SupportTraitDi...
[hiphop-php.git] / hphp / util / type-scan.h
blob58718ded0b68583cd26a199fc967259bc01caebf
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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 +----------------------------------------------------------------------+
17 #pragma once
19 #include <cstdint>
20 #include <stdexcept>
21 #include <type_traits>
22 #include <utility>
23 #include <vector>
25 #include "hphp/util/assertions.h"
26 #include "hphp/util/portability.h"
29 * "Type scanners" is machinery to automatically generate functions to walk
30 * instances of arbitrary types. These functions report pointers to other
31 * allocated types. These will be used by the marking phase of the garbage
32 * collector. This avoids having to write manual scan functions for the large
33 * number of types which can be allocated in the request heap.
35 * Basic use: Call type_scan::init() as early as possible. Tag any allocation
36 * out of the request heap by calling getIndexForMalloc<T>() (where T is the
37 * type being allocated) and storing the returned type-index somewhere it can be
38 * retrieved later. Then when trying to scan that allocation, retrieve the
39 * type-index, and call the Scanner::scanByIndex() passing in the type-index. If
40 * one wishes to scan a type which isn't request heap allocated (for example, a
41 * root), use Scanner::scan<T>() instead.
43 * That's the basic use case. One can customize this greatly by using custom
44 * actions at the allocation site (see below), and adding custom annotations to
45 * the types being scanned. Most users don't need to concern themselves with any
46 * of this, as most of the complexity is hidden behind the allocator interface
47 * and standard container replacements.
49 * Note that there are certain constructs that can appear in types which the
50 * scanner generator cannot handle automatically. They include (but may not be
51 * exhaustive):
53 * - Pointers to void
54 * - Unions (if the different members do not have the same runtime layout)
55 * - Virtual inheritance
56 * - Arrays of indeterminate size
58 * If any of these occur, there will be an error while generating the functions,
59 * and annotations will be required to resolve (see below).
62 namespace HPHP::type_scan {
64 ////////////////////////////////////////////////////////////////////////////////
67 * Type index used to represent a specific type allocated with optional
68 * attributes. The same type can have multiple type indices depending on the
69 * context.
71 * "kIndexUnknown" and "kIndexUnknownNoPtrs" are special type indices
72 * representing an unknown type, with the later being an assertion that the type
73 * contains no pointers. These are used for contexts where the type you're
74 * allocating isn't statically known, and also for allocations before the
75 * type-scanning infrastructure is initialized. The type index "kIndexUnknown"
76 * always implies conservative scanning.
79 // Use 16-bits to represent the type index for now. That's more than enough for
80 // our purposes currently. If we ever exceed it, the generated scanners will
81 // fail to compile with a static assertion.
82 using Index = std::uint16_t;
83 constexpr const Index kIndexUnknown = 0;
84 constexpr const Index kIndexUnknownNoPtrs = 1;
86 ////////////////////////////////////////////////////////////////////////////////
90 // Various ugly internal implementation details put here not to muddle the
91 // external interface. Look in here if you're interested in implementation
92 // comments.
93 #include "hphp/util/type-scan-detail.h"
95 namespace HPHP::type_scan { namespace Action {
97 ////////////////////////////////////////////////////////////////////////////////
100 * When obtaining a type-index via getIndexForMalloc<T>(), one can optionally
101 * provide an "action" to go along with this type-index. This action influences
102 * the nature of the scanner function generated for the type. This is why a
103 * particular type can have multiple type-indices, they might have different
104 * actions. These actions are empty types which are passed in as template
105 * parameters.
108 // The default, automatically generate a scanner function.
109 struct Auto {};
111 // Don't generate a scanner function for this type-index, be a no-op. This is
112 // preferable to using kIndexUnknownNoPtrs when you know the type, since it
113 // preserves the actual type.
114 struct Ignore {};
116 // Conservative scan this type. If a list of types is provided in the template
117 // instantiation, only conservative scan if the scanner generator believes any
118 // of the given types potentially have pointers to request allocated memory. If
119 // not, ignore the type. If the list is empty, always conservative scan.
120 template <typename... T> struct Conservative {};
122 // Normally, if a scanner function for T receives a pointer to a block of memory
123 // larger than sizeof(T), it assumes an array of T had been allocated, and runs
124 // the scanner function for each element. If "WithSuffix<U>" action
125 // (instantiated on type U) is used in this case, it is assumed only for the
126 // first sizeof(T) bytes is a T. The rest of the block is assumed to contain an
127 // array of type U, and a scanner appropriate for U is used on that
128 // portion. This is meant to be used for types which utilize "flexible array
129 // members" where some variable amount of allocated after the main object.
130 template <typename T> struct WithSuffix {};
132 ////////////////////////////////////////////////////////////////////////////////
136 // The type scanners need to know which types are "collectable". A collectable
137 // type is one with a reference count that is explicitly managed. The ultimate
138 // goal for the type scanners is to find all the pointers to collectable types.
139 // To mark a type as being collectable, instantiate MarkCollectable<> on the
140 // type. Its usually easiest to have the type T derive from MarkCollectable<T>.
141 template <typename T> struct MarkCollectable {};
143 // Normally countable types are never scanned, even if explicitly
144 // requested. However, you may want to scan a countable type in certain contexts
145 // (for example, a countable type which can be both allocated in memory and the
146 // stack). In that case, use this marker instead.
147 template <typename T> struct MarkScannableCollectable {};
149 // Obtain a type index for the given type T and an optional action. Asserts that
150 // this index will be used to scan T, and that T is being allocated here.
151 template <typename T, typename Action = Action::Auto>
152 inline Index getIndexForMalloc() {
153 // Why do this instead of detail::Indexer<>::s_index ? Because otherwise Clang
154 // decides not to emit all the debug information related to the Indexer.
155 detail::Indexer<typename std::remove_cv<T>::type, Action> temp;
156 return temp.s_index;
159 // Obtain a type index for the given type T. Asserts that this index will be
160 // used only to scan the T, and that T is *not* being allocated here.
161 template <typename T>
162 inline Index getIndexForScan() {
163 // Why do this instead of detail::Indexer<>::s_index ? Because otherwise Clang
164 // decides not to emit all the debug information related to the Indexer.
165 detail::Indexer<typename std::remove_cv<T>::type, detail::ScanAction> temp;
166 return temp.s_index;
169 // Obtain the name of the type associated with the given type index.
170 inline const char* getName(Index index) {
171 assert(index < detail::g_metadata_table_size);
172 return detail::g_metadata_table[index].m_name;
175 // Return true if any of the generated scanners is non-conservative. This will
176 // return false before init() is called, as only conservative scanning is done
177 // until that.
178 inline bool hasNonConservative() {
179 return detail::g_metadata_table_size > 2;
182 // Return true if index is a valid type or if everything is conservative
183 inline bool isKnownType(Index index) {
184 return !hasNonConservative() || index != kIndexUnknown;
187 inline bool hasScanner(Index index) {
188 assert(index < detail::g_metadata_table_size);
189 return detail::g_metadata_table[index].m_scan !=
190 detail::g_metadata_table[kIndexUnknownNoPtrs].m_scan;
193 inline bool hasConservativeScanner(Index index) {
194 assert(index < detail::g_metadata_table_size);
195 return detail::g_metadata_table[index].m_scan ==
196 detail::g_metadata_table[kIndexUnknown].m_scan;
199 // Initialize the type scanner infrastructure. Before this is done,
200 // getIndexForMalloc() will always return kIndexUnknown and any attempts to scan
201 // will use conservative scanning. For this reason, its important to call init()
202 // as early as possible.
203 void init(const std::string& extractPath,
204 const std::string& fallbackPath,
205 bool trust);
207 // Thrown by init() if initialization fails.
208 struct InitException: std::runtime_error {
209 using std::runtime_error::runtime_error;
213 * Scanner is what actually performs the scanning (one cannot call the generated
214 * functions directly). A scanner is also passed into any type custom scanner
215 * functions. Once instantiated, one can call scan functions on it to gather
216 * pointers, then retrieve the pointers once done. The same Scanner can be
217 * re-used this way multiple times.
219 struct Scanner {
221 * scan() overloads:
223 * Scan an instance of a statically known type. This should be used from
224 * within type custom scanners, or for things like roots inside the GC. For
225 * scanning objects in the request heap, scanByIndex() should instead by used.
227 * There's various overloads for scan() to customize behavior statically based
228 * on the type.
231 // Overload for interesting pointer types. "Scanning" a pointer is just
232 // enqueuing it, so do that.
233 template <typename T>
234 typename std::enable_if<std::is_pointer<T>::value>::type
235 scan(const T& ptr, std::size_t size = sizeof(T)) {
236 static_assert(!detail::UnboundedArray<T>::value,
237 "Trying to scan unbounded array");
238 // scan contiguous array of pointers: insert addr of each pointer
239 assert(size % sizeof(T) == 0);
240 for (auto p = &ptr, e = p + size / sizeof(T); p < e; ++p) {
241 m_addrs.emplace_back((const void**)p);
245 // Overload for interesting non-pointer types.
246 template <typename T>
247 typename std::enable_if<!std::is_pointer<T>::value>::type
248 scan(const T& val, std::size_t size = sizeof(T)) {
249 static_assert(!detail::IsVoid<T>::value,
250 "Trying to scan void pointer(s). "
251 "Please provide a more specific type.");
252 static_assert(!detail::UnboundedArray<T>::value,
253 "Trying to scan unbounded array");
254 assert(size % sizeof(T) == 0);
255 scanByIndex(getIndexForScan<T>(), &val, size);
258 // Report a range to be conservative scanned. Meant to be called from a type
259 // custom scanner.
260 void conservative(const void* ptr, std::size_t size) {
261 m_conservative.emplace_back(ptr, size);
264 // Scan a region of memory using the given type-index.
265 void scanByIndex(Index index, const void* ptr, std::size_t size) {
266 assert(index < detail::g_metadata_table_size);
267 detail::g_metadata_table[index].m_scan(*this, ptr, size);
270 // Add a weak pointer.
271 void weak(const void* ptr) {
272 m_weak.emplace_back(ptr);
275 // Called once all the scanning is done. Callbacks report different
276 // pointer types:
277 // F1 - called to report conservative ranges
278 // F2 - called to report addresses of pointers
279 // F3 - called to report weak pointers
280 // Afterwards, all the state is cleared, and the scanner can be re-used.
281 template <typename F1, typename F2, typename F3>
282 void finish(F1&& f1, F2&& f2, F3&& f3) {
283 for (auto r : m_conservative) {
284 f1(r.first, r.second);
286 for (auto addr : m_addrs) {
287 f2(addr);
289 for (auto weak : m_weak) {
290 f3(weak);
292 m_addrs.clear();
293 m_conservative.clear();
294 m_weak.clear();
297 // These are logically private, but they're public so that the generated
298 // functions can manipulate them directly.
299 std::vector<const void**> m_addrs; // pointer locations
300 std::vector<std::pair<const void*, std::size_t>> m_conservative;
301 std::vector<const void*> m_weak;
305 * Type annotations to change generated function behavior:
307 * The below macros provide ways to describe certain information about types to
308 * the function generator which changes how the function is scanned. There are
309 * certain constructs which the scanner generator cannot handle, so in those
310 * cases an annotation is required to resolve that.
312 * All these annotations must be placed within the type's definition. However,
313 * it doesn't matter if they're placed in a public/protected/private section.
314 * If a custom scanner function is provided, the type *must* have external
315 * linkage (IE, not in an anonymous namespace).
318 // Provide a custom scanner function for this entire type. The generated
319 // function will not attempt to do anything with the type, but just call this
320 // function. It is the custom scanner's responsibility to scan/enqueue all
321 // members. Note that the generated function will still attempt to scan any
322 // bases normally.
324 // Warning: these functions will not be called unless exact scanners were
325 // generated and are being used. Conservative-scan will not call them,
326 // so the underlying fields must be conservative-scannable to start with.
327 // Importantly, std containers are not conservatively scannable.
328 #define TYPE_SCAN_CUSTOM(...) \
329 static constexpr const \
330 HPHP::type_scan::detail::Custom<__VA_ARGS__> \
331 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
332 TYPE_SCAN_CUSTOM_GUARD_NAME{}; \
333 void TYPE_SCAN_CUSTOM_NAME(HPHP::type_scan::Scanner& scanner) const \
334 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
336 // Provide a custom scanner for a single field. The generated function will only
337 // call this scanner for this specific field, and scan the rest normally.
338 #define TYPE_SCAN_CUSTOM_FIELD(FIELD) \
339 void TYPE_SCAN_BUILD_NAME(TYPE_SCAN_CUSTOM_FIELD_NAME, FIELD)( \
340 HPHP::type_scan::Scanner& scanner) const \
341 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
343 // Provide a custom scanner for a list of base classes. The generated function
344 // will use this scanner instead of scanning the specified bases. This is useful
345 // for base classes which you cannot modify the definition of (or if using
346 // virtual inheritance).
347 #define TYPE_SCAN_CUSTOM_BASES(...) \
348 static constexpr const \
349 HPHP::type_scan::detail::CustomBase<__VA_ARGS__> \
350 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
351 TYPE_SCAN_CUSTOM_BASES_NAME{}; \
352 void TYPE_SCAN_CUSTOM_BASES_SCANNER_NAME( \
353 HPHP::type_scan::Scanner& scanner) const \
354 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
356 // Ignore everything about this type, but scan any base classes as normal.
357 #define TYPE_SCAN_IGNORE_ALL \
358 static constexpr const \
359 HPHP::type_scan::detail::IgnoreField \
360 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
361 TYPE_SCAN_IGNORE_NAME{}
363 // Ignore a single field, but scan the rest as normal.
364 #define TYPE_SCAN_IGNORE_FIELD(FIELD) \
365 static constexpr const \
366 HPHP::type_scan::detail::IgnoreField \
367 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
368 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_IGNORE_FIELD_NAME, FIELD){}
370 // Ignore the specified list of base classes.
371 #define TYPE_SCAN_IGNORE_BASES(...) \
372 static constexpr const \
373 HPHP::type_scan::detail::IgnoreBase<__VA_ARGS__> \
374 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
375 TYPE_SCAN_IGNORE_BASE_NAME{}
377 // Conservative scan the entire type, but scan any base classes as normal.
378 #define TYPE_SCAN_CONSERVATIVE_ALL \
379 static constexpr const \
380 HPHP::type_scan::detail::ConservativeField \
381 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
382 TYPE_SCAN_CONSERVATIVE_NAME{}
384 // Conservative scan a single field, but scan the rest as normal.
385 #define TYPE_SCAN_CONSERVATIVE_FIELD(FIELD) \
386 static constexpr const \
387 HPHP::type_scan::detail::ConservativeField \
388 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
389 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_CONSERVATIVE_FIELD_NAME, FIELD){}
391 // Mark a field as being a "flexible array". IE, an array without a size as the
392 // last member. This needs to be marked explicitly as sometimes the flexible
393 // array field starts within the object, sometimes not. Only one field in a type
394 // can be marked as such.
395 #define TYPE_SCAN_FLEXIBLE_ARRAY_FIELD(FIELD) \
396 static constexpr const \
397 HPHP::type_scan::detail::FlexibleArrayField \
398 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
399 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_FLEXIBLE_ARRAY_FIELD_NAME, FIELD){}
401 // "Silence" a base class from a forbidden template error. There's a set of
402 // template types which are forbidden from containing request heap allocated
403 // objects, and the scanner generator will attempt to verify this. This opts out
404 // a list of base classes from that particular check for this specific type.
405 #define TYPE_SCAN_SILENCE_FORBIDDEN_BASES(...) \
406 static constexpr const \
407 HPHP::type_scan::detail::SilenceForbiddenBase<__VA_ARGS__> \
408 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
409 TYPE_SCAN_SILENCE_FORBIDDEN_BASE_NAME{}
411 ////////////////////////////////////////////////////////////////////////////////