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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_RUNTIME_BASE_REQ_MALLOC_H_
18 #define incl_HPHP_RUNTIME_BASE_REQ_MALLOC_H_
20 #include "hphp/util/type-scan.h"
23 * req::malloc api for request-scoped memory
25 * This is the most generic entry point to the request local
26 * allocator. If you easily know the size of the allocation at free
27 * time, it might be more efficient to use MM() apis directly.
29 * These functions behave like C's malloc/free, but get memory from
30 * the current thread's MemoryManager instance. At request-end, any
31 * un-freed memory is explicitly freed (and in debug, garbage filled).
32 * If any pointers to this memory survive beyond a request, they'll be
35 * These functions only guarantee 8-byte alignment for the returned
39 namespace HPHP
{ namespace req
{
41 ////////////////////////////////////////////////////////////////////////////////
44 * Plain malloc-style allocation in the request heap is not available;
45 * please choose one of the variants below. Memory obtained through any
46 * of these will be freed at end-of-request, unless passed back to req::free().
48 * 1. malloc_noptrs, if you know the memory will not contain heap pointers,
49 * e.g. c-strings, pixels, compressed or encrypted data, etc.
51 * 2. make_raw<T>(...) or make_raw_array<T>(count), if you know the type,
52 * whether or not it contains pointers. These are analogs of C++ new.
54 * 3. malloc(type_scan::Index) like make_raw<T>, but you provide the type id,
55 * which must not be type_scan::kIndexUnknown; intended for implementing
58 * 4. malloc_unk() memory will be treated as root and conservative scanned,
59 * because we don't know whether or not it will have pointers.
61 void* malloc(size_t nbytes
) = delete;
62 void* calloc(size_t count
, size_t bytes
) = delete;
63 void* realloc(void* ptr
, size_t nbytes
) = delete;
66 * Interfaces to receive raw memory. Whenever possible, prefer the typed
67 * interfaces below, such as make_raw<T>.
69 void* malloc(size_t nbytes
, type_scan::Index
);
70 void* calloc(size_t count
, size_t bytes
, type_scan::Index
);
71 void* realloc(void* ptr
, size_t nbytes
, type_scan::Index
);
73 // Unknown type-index, conservative scan contents and treat as root.
74 void* malloc_untyped(size_t nbytes
);
75 void* calloc_untyped(size_t count
, size_t bytes
);
76 void* realloc_untyped(void* ptr
, size_t nbytes
);
78 // Unknown type-index, but assert there's no pointers within.
79 inline void* malloc_noptrs(size_t nbytes
) {
80 return malloc(nbytes
, type_scan::kIndexUnknownNoPtrs
);
82 inline void* calloc_noptrs(size_t count
, size_t bytes
) {
83 return calloc(count
, bytes
, type_scan::kIndexUnknownNoPtrs
);
85 inline void* realloc_noptrs(void* ptr
, size_t nbytes
) {
86 return realloc(ptr
, nbytes
, type_scan::kIndexUnknownNoPtrs
);
89 char* strndup(const char* str
, size_t len
);
94 * request-heap (de)allocators for non-POD C++-style stuff. Runs constructors
97 * Unlike the normal operator delete, req::destroy_raw() requires ~T() must
98 * be nothrow and that p is not null.
100 template<class T
, class... Args
> T
* make_raw(Args
&&...);
101 template<class T
> void destroy_raw(T
* p
);
104 * Allocate an array of objects. Similar to req::malloc, but with
105 * support for constructors.
107 * Note that explicitly calling req::destroy_raw will run the destructors,
108 * but if you let the allocator sweep it the destructors will not be
111 * Unlike the normal operator delete, req::destroy_raw_array requires
112 * ~T() must be nothrow.
114 template<class T
> T
* make_raw_array(size_t count
);
115 template<class T
> void destroy_raw_array(T
* t
, size_t count
);
118 * Allocate an array of objects, memset to 0. Does *not* run any constructors.
120 template<class T
> T
* calloc_raw_array(size_t count
);
122 //////////////////////////////////////////////////////////////////////
124 // STL-style allocator for the request-heap allocator. (Unfortunately we
125 // can't use allocator_traits yet.)
127 // You can also use req::Allocator as a model of folly's
128 // SimpleAllocator where appropriate.
131 template <class T
, typename Action
= type_scan::Action::Auto
>
133 typedef T value_type
;
135 typedef const T
* const_pointer
;
136 typedef T
& reference
;
137 typedef const T
& const_reference
;
138 typedef std::size_t size_type
;
139 typedef std::ptrdiff_t difference_type
;
143 typedef Allocator
<U
, Action
> other
;
146 pointer
address(reference value
) {
149 const_pointer
address(const_reference value
) const {
153 Allocator() noexcept
{}
154 Allocator(const Allocator
&) noexcept
{}
155 template<class U
, typename A
> Allocator(const Allocator
<U
,A
>&) noexcept
{}
156 ~Allocator() noexcept
{}
158 Allocator
& operator=(const Allocator
&) noexcept
{ return *this; }
160 size_type
max_size() const {
161 return std::numeric_limits
<std::size_t>::max() / sizeof(T
);
164 pointer
allocate(size_type num
, const void* = 0) {
165 pointer ret
= (pointer
)req::malloc(
167 type_scan::getIndexForMalloc
<T
, Action
>()
172 template<class U
, class... Args
>
173 void construct(U
* p
, Args
&&... args
) {
174 ::new ((void*)p
) U(std::forward
<Args
>(args
)...);
177 void destroy(pointer p
) {
181 void deallocate(pointer p
, size_type num
) {
185 template<class U
, typename A
> bool operator==(const Allocator
<U
,A
>&) const {
189 template<class U
, typename A
> bool operator!=(const Allocator
<U
,A
>&) const {
194 // Variant of Allocator which indicates to the GC type-scanning machinery T
195 // should be conservative scanned. Meant to be used for container internal
196 // allocations where we don't want to attempt to exactly scan the internal
197 // contents. Such containers often using type-punning and other tricks, which
198 // means an exact scan will fail to find valid pointers (where as conservative
199 // scan will). Where-ever possible, we'll use the container's public interface
200 // to scan the values it holds in an exact manner.
202 using ConservativeAllocator
= Allocator
<T
, type_scan::Action::Conservative
<T
>>;
204 /////////////////////////////////////////////////////////////////////
206 template<class T
, class... Args
> T
* make_raw(Args
&&... args
) {
207 auto const mem
= req::malloc(sizeof(T
), type_scan::getIndexForMalloc
<T
>());
209 return new (mem
) T(std::forward
<Args
>(args
)...);
216 template<class T
> void destroy_raw(T
* t
) {
221 template<class T
> T
* make_raw_array(size_t count
) {
222 T
* ret
= static_cast<T
*>(
223 req::malloc(count
* sizeof(T
), type_scan::getIndexForMalloc
<T
>())
227 for (; i
< count
; ++i
) {
242 void destroy_raw_array(T
* t
, size_t count
) {
250 template<class T
> T
* calloc_raw_array(size_t count
) {
251 return static_cast<T
*>(
252 req::calloc(count
, sizeof(T
), type_scan::getIndexForMalloc
<T
>())
256 ////////////////////////////////////////////////////////////////////////////////