2 +----------------------------------------------------------------------+
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 +----------------------------------------------------------------------+
21 #include <type_traits>
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
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
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
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
108 // The default, automatically generate a scanner function.
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.
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
;
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
;
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
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
,
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.
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
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
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
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
) {
289 for (auto weak
: m_weak
) {
293 m_conservative
.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
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 ////////////////////////////////////////////////////////////////////////////////