Do not use std::containers in request roots
[hiphop-php.git] / hphp / util / type-scan.h
blobf664c7b52ec25e4415eb90b7c82cb42bcb4ca14f
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 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 #ifndef incl_HPHP_UTIL_TYPE_SCAN_H_
18 #define incl_HPHP_UTIL_TYPE_SCAN_H_
20 #include <cstdint>
21 #include <stdexcept>
22 #include <type_traits>
23 #include <unordered_set>
24 #include <utility>
25 #include <vector>
27 #include "hphp/util/assertions.h"
28 #include "hphp/util/portability.h"
31 * "Type scanners" is machinery to automatically generate functions to walk
32 * instances of arbitrary types. These functions report pointers to other
33 * allocated types. These will be used by the marking phase of the garbage
34 * collector. This avoids having to write manual scan functions for the large
35 * number of types which can be allocated in the request heap.
37 * Basic use: Call type_scan::init() as early as possible. Tag any allocation
38 * out of the request heap by calling getIndexForMalloc<T>() (where T is the
39 * type being allocated) and storing the returned type-index somewhere it can be
40 * retrieved later. Then when trying to scan that allocation, retrieve the
41 * type-index, and call the Scanner::scanByIndex() passing in the type-index. If
42 * one wishes to scan a type which isn't request heap allocated (for example, a
43 * root), use Scanner::scan<T>() instead.
45 * That's the basic use case. One can customize this greatly by using custom
46 * actions at the allocation site (see below), and adding custom annotations to
47 * the types being scanned. Most users don't need to concern themselves with any
48 * of this, as most of the complexity is hidden behind the allocator interface
49 * and standard container replacements.
51 * Note that there are certain constructs that can appear in types which the
52 * scanner generator cannot handle automatically. They include (but may not be
53 * exhaustive):
55 * - Pointers to void
56 * - Unions (if the different members do not have the same runtime layout)
57 * - Virtual inheritance
58 * - Arrays of indeterminate size
60 * If any of these occur, there will be an error while generating the functions,
61 * and annotations will be required to resolve (see below).
64 namespace HPHP { namespace type_scan {
66 ////////////////////////////////////////////////////////////////////////////////
69 * Type index used to represent a specific type allocated with optional
70 * attributes. The same type can have multiple type indices depending on the
71 * context.
73 * "kIndexUnknown" and "kIndexUnknownNoPtrs" are special type indices
74 * representing an unknown type, with the later being an assertion that the type
75 * contains no pointers. These are used for contexts where the type you're
76 * allocating isn't statically known, and also for allocations before the
77 * type-scanning infrastructure is initialized. The type index "kIndexUnknown"
78 * always implies conservative scanning.
81 // Use 16-bits to represent the type index for now. That's more than enough for
82 // our purposes currently. If we ever exceed it, the generated scanners will
83 // fail to compile with a static assertion.
84 using Index = std::uint16_t;
85 constexpr const Index kIndexUnknown = 0;
86 constexpr const Index kIndexUnknownNoPtrs = 1;
88 ////////////////////////////////////////////////////////////////////////////////
92 // Various ugly internal implementation details put here not to muddle the
93 // external interface. Look in here if you're interested in implementation
94 // comments.
95 #include "hphp/util/type-scan-detail.h"
97 namespace HPHP { namespace type_scan { namespace Action {
99 ////////////////////////////////////////////////////////////////////////////////
102 * When obtaining a type-index via getIndexForMalloc<T>(), one can optionally
103 * provide an "action" to go along with this type-index. This action influences
104 * the nature of the scanner function generated for the type. This is why a
105 * particular type can have multiple type-indices, they might have different
106 * actions. These actions are empty types which are passed in as template
107 * parameters.
110 // The default, automatically generate a scanner function.
111 struct Auto {};
113 // Don't generate a scanner function for this type-index, be a no-op. This is
114 // preferable to using kIndexUnknownNoPtrs when you know the type, since it
115 // preserves the actual type.
116 struct Ignore {};
118 // Conservative scan this type. If a list of types is provided in the template
119 // instantiation, only conservative scan if the scanner generator believes any
120 // of the given types potentially have pointers to request allocated memory. If
121 // not, ignore the type. If the list is empty, always conservative scan.
122 template <typename... T> struct Conservative {};
124 // Normally, if a scanner function for T receives a pointer to a block of memory
125 // larger than sizeof(T), it assumes an array of T had been allocated, and runs
126 // the scanner function for each element. If "WithSuffix<U>" action
127 // (instantiated on type U) is used in this case, it is assumed only for the
128 // first sizeof(T) bytes is a T. The rest of the block is assumed to contain an
129 // array of type U, and a scanner appropriate for U is used on that
130 // portion. This is meant to be used for types which utilize "flexible array
131 // members" where some variable amount of allocated after the main object.
132 template <typename T> struct WithSuffix {};
134 ////////////////////////////////////////////////////////////////////////////////
138 // The type scanners need to know which types are "countable". A countable type
139 // is one with a reference count that is explicitly managed. The ultimate goal
140 // for the type scanners is to find all the pointers to countable types. To mark
141 // a type as being countable, instantiate MarkCountable<> on the type. Its
142 // usually easiest to have the type T derive from MarkCountable<T>.
143 template <typename T> struct MarkCountable {};
145 // Normally countable types are never scanned, even if explicitly
146 // requested. However, you may want to scan a countable type in certain contexts
147 // (for example, a countable type which can be both allocated in memory and the
148 // stack). In that case, use this marker instead.
149 template <typename T> struct MarkScannableCountable {};
151 // Obtain a type index for the given type T and an optional action. Asserts that
152 // this index will be used to scan T, and that T is being allocated here.
153 template <typename T, typename Action = Action::Auto>
154 inline Index getIndexForMalloc() {
155 // Why do this instead of detail::Indexer<>::s_index ? Because otherwise Clang
156 // decides not to emit all the debug information related to the Indexer.
157 detail::Indexer<typename std::remove_cv<T>::type, Action> temp;
158 return temp.s_index;
161 // Obtain a type index for the given type T. Asserts that this index will be
162 // used only to scan the T, and that T is *not* being allocated here.
163 template <typename T>
164 inline Index getIndexForScan() {
165 // Why do this instead of detail::Indexer<>::s_index ? Because otherwise Clang
166 // decides not to emit all the debug information related to the Indexer.
167 detail::Indexer<typename std::remove_cv<T>::type, detail::ScanAction> temp;
168 return temp.s_index;
171 // Obtain the name of the type associated with the given type index.
172 inline const char* getName(Index index) {
173 assert(index < detail::g_metadata_table_size);
174 return detail::g_metadata_table[index].m_name;
177 // Return true if any of the generated scanners is non-conservative. This will
178 // return false before init() is called, as only conservative scanning is done
179 // until that.
180 inline bool hasNonConservative() {
181 return detail::g_metadata_table_size > 2;
184 // Initialize the type scanner infrastructure. Before this is done,
185 // getIndexForMalloc() will always return kIndexUnknown and any attempts to scan
186 // will use conservative scanning. For this reason, its important to call init()
187 // as early as possible.
188 void init();
190 // Thrown by init() if initialization fails.
191 struct InitException: std::runtime_error {
192 using std::runtime_error::runtime_error;
196 * Scanner is what actually performs the scanning (one cannot call the generated
197 * functions directly). A scanner is also passed into any type custom scanner
198 * functions. Once instantiated, one can call scan functions on it to gather
199 * pointers, then retrieve the pointers once done. The same Scanner can be
200 * re-used this way multiple times.
202 struct Scanner {
203 // Enqueue a pointer into this scanner to be reported later. This is meant to
204 // be called from type custom scanner functions to report interesting
205 // pointers.
206 template <typename T> void enqueue(const T* ptr) {
207 // Don't allow void*
208 static_assert(!detail::IsVoid<T>::value,
209 "Trying to enqueue void pointer(s). "
210 "Please provide a more specific type.");
211 // Certain types are statically uninteresting, so don't enqueue pointers to
212 // those.
213 if (detail::Uninteresting<T*>::value) return;
214 m_ptrs.emplace_back(ptr);
218 * scan() overloads:
220 * Scan an instance of a statically known type. This should be used from
221 * within type custom scanners, or for things like roots inside the GC. For
222 * scanning objects in the request heap, scanByIndex() should instead by used.
224 * There's various overloads for scan() to customize behavior statically based
225 * on the type.
228 // Overload for types where we statically know the type isn't interesting, so
229 // do nothing.
230 template <typename T> typename std::enable_if<
231 detail::Uninteresting<T>::value
232 >::type
233 scan(const T&, std::size_t size = sizeof(T)) {
234 // Even though this function is a nop, still try to catch errors like trying
235 // to scan an unbounded array.
236 static_assert(!detail::UnboundedArray<T>::value,
237 "Trying to scan unbounded array");
238 assert(size % sizeof(T) == 0);
241 // Overload for interesting pointer types. "Scanning" a pointer is just
242 // enqueuing it, so do that.
243 template <typename T> typename std::enable_if<
244 std::is_pointer<T>::value && !detail::Uninteresting<T>::value
245 >::type
246 scan(const T& ptr, std::size_t size = sizeof(T)) {
247 // No pointers to void or unbounded arrays.
248 static_assert(!detail::IsVoid<T>::value,
249 "Trying to scan void pointer(s). "
250 "Please provide a more specific type.");
251 static_assert(!detail::UnboundedArray<T>::value,
252 "Trying to scan unbounded array");
254 assert(size % sizeof(T) == 0);
255 const auto raw = reinterpret_cast<std::uintptr_t>(ptr);
256 for (std::size_t i = 0; i < size; i += sizeof(T)) {
257 enqueue(reinterpret_cast<const T>(raw + i));
261 // Overload for interesting non-pointer types.
262 template <typename T> typename std::enable_if<
263 !std::is_pointer<T>::value && !detail::Uninteresting<T>::value
264 >::type
265 scan(const T& val, std::size_t size = sizeof(T)) {
266 static_assert(!detail::IsVoid<T>::value,
267 "Trying to scan void pointer(s). "
268 "Please provide a more specific type.");
269 static_assert(!detail::UnboundedArray<T>::value,
270 "Trying to scan unbounded array");
271 assert(size % sizeof(T) == 0);
272 scanByIndex(getIndexForScan<T>(), &val, size);
275 // Report a range to be conservative scanned. Meant to be called from a type
276 // custom scanner.
277 void conservative(const void* ptr, std::size_t size) {
278 m_conservative.emplace_back(ptr, size);
281 // Scan a region of memory using the given type-index.
282 void scanByIndex(Index index, const void* ptr, std::size_t size) {
283 assert(index < detail::g_metadata_table_size);
284 if (auto scan = detail::g_metadata_table[index].m_scan) {
285 scan(*this, ptr, size);
289 // Called once all the scanning is done. Reports enqueued pointers via the
290 // first passed callback, and conservative ranges via the second passed
291 // callback. Afterwards, all the state is cleared. The Scanner can be re-used
292 // after this.
293 template <typename F1, typename F2> void finish(F1&& f1, F2&& f2) {
294 for (const auto& p : m_ptrs) if (p) { f1(p); }
295 for (const auto& p : m_conservative) f2(p.first, p.second);
296 m_ptrs.clear();
297 m_conservative.clear();
300 // These are logically private, but they're public so that the generated
301 // functions can manipulate them directly.
302 std::vector<const void*> m_ptrs;
303 std::vector<std::pair<const void*, std::size_t>> m_conservative;
307 * Type annotations to change generated function behavior:
309 * The below macros provide ways to describe certain information about types to
310 * the function generator which changes how the function is scanned. There are
311 * certain constructs which the scanner generator cannot handle, so in those
312 * cases an annotation is required to resolve that.
314 * All these annotations must be placed within the type's definition. However,
315 * it doesn't matter if they're placed in a public/protected/private section.
316 * If a custom scanner function is provided, the type *must* have external
317 * linkage (IE, not in an anonymous namespace).
320 // Provide a custom scanner function for this entire type. The generated
321 // function will not attempt to do anything with the type, but just call this
322 // function. It is the custom scanner's responsibility to scan/enqueue all
323 // members. Note that the generated function will still attempt to scan any
324 // bases normally.
326 // Warning: these functions will not be called unless exact scanners were
327 // generated and are being used. Conservative-scan will not call them,
328 // so the underlying fields must be conservative-scannable to start with.
329 // Importantly, std containers are not conservatively scannable.
330 #define TYPE_SCAN_CUSTOM(...) \
331 static constexpr const \
332 HPHP::type_scan::detail::Custom<__VA_ARGS__> \
333 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
334 TYPE_SCAN_CUSTOM_GUARD_NAME{}; \
335 void TYPE_SCAN_CUSTOM_NAME(HPHP::type_scan::Scanner& scanner) const \
336 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
338 // Provide a custom scanner for a single field. The generated function will only
339 // call this scanner for this specific field, and scan the rest normally.
340 #define TYPE_SCAN_CUSTOM_FIELD(FIELD) \
341 void TYPE_SCAN_BUILD_NAME(TYPE_SCAN_CUSTOM_FIELD_NAME, FIELD)( \
342 HPHP::type_scan::Scanner& scanner) const \
343 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
345 // Provide a custom scanner for a list of base classes. The generated function
346 // will use this scanner instead of scanning the specified bases. This is useful
347 // for base classes which you cannot modify the definition of (or if using
348 // virtual inheritance).
349 #define TYPE_SCAN_CUSTOM_BASES(...) \
350 static constexpr const \
351 HPHP::type_scan::detail::CustomBase<__VA_ARGS__> \
352 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
353 TYPE_SCAN_CUSTOM_BASES_NAME{}; \
354 void TYPE_SCAN_CUSTOM_BASES_SCANNER_NAME( \
355 HPHP::type_scan::Scanner& scanner) const \
356 ATTRIBUTE_USED ATTRIBUTE_UNUSED EXTERNALLY_VISIBLE
358 // Ignore everything about this type, but scan any base classes as normal.
359 #define TYPE_SCAN_IGNORE_ALL \
360 static constexpr const \
361 HPHP::type_scan::detail::IgnoreField \
362 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
363 TYPE_SCAN_IGNORE_NAME{}
365 // Ignore a single field, but scan the rest as normal.
366 #define TYPE_SCAN_IGNORE_FIELD(FIELD) \
367 static constexpr const \
368 HPHP::type_scan::detail::IgnoreField \
369 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
370 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_IGNORE_FIELD_NAME, FIELD){}
372 // Ignore the specified list of base classes.
373 #define TYPE_SCAN_IGNORE_BASES(...) \
374 static constexpr const \
375 HPHP::type_scan::detail::IgnoreBase<__VA_ARGS__> \
376 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
377 TYPE_SCAN_IGNORE_BASE_NAME{}
379 // Conservative scan the entire type, but scan any base classes as normal.
380 #define TYPE_SCAN_CONSERVATIVE_ALL \
381 static constexpr const \
382 HPHP::type_scan::detail::ConservativeField \
383 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
384 TYPE_SCAN_CONSERVATIVE_NAME{}
386 // Conservative scan a single field, but scan the rest as normal.
387 #define TYPE_SCAN_CONSERVATIVE_FIELD(FIELD) \
388 static constexpr const \
389 HPHP::type_scan::detail::ConservativeField \
390 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
391 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_CONSERVATIVE_FIELD_NAME, FIELD){}
393 // Mark a field as being a "flexible array". IE, an array without a size as the
394 // last member. This needs to be marked explicitly as sometimes the flexible
395 // array field starts within the object, sometimes not. Only one field in a type
396 // can be marked as such.
397 #define TYPE_SCAN_FLEXIBLE_ARRAY_FIELD(FIELD) \
398 static constexpr const \
399 HPHP::type_scan::detail::FlexibleArrayField \
400 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
401 TYPE_SCAN_BUILD_NAME(TYPE_SCAN_FLEXIBLE_ARRAY_FIELD_NAME, FIELD){}
403 // "Silence" a base class from a forbidden template error. There's a set of
404 // template types which are forbidden from containing request heap allocated
405 // objects, and the scanner generator will attempt to verify this. This opts out
406 // a list of base classes from that particular check for this specific type.
407 #define TYPE_SCAN_SILENCE_FORBIDDEN_BASES(...) \
408 static constexpr const \
409 HPHP::type_scan::detail::SilenceForbiddenBase<__VA_ARGS__> \
410 ATTRIBUTE_USED ATTRIBUTE_UNUSED \
411 TYPE_SCAN_SILENCE_FORBIDDEN_BASE_NAME{}
413 ////////////////////////////////////////////////////////////////////////////////
417 #endif