nlib
NMalloc.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
17 #define INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
18 
19 #include <errno.h>
20 #include <stddef.h>
21 #include <stdlib.h> // for malloc/free
22 
23 #ifdef __cplusplus
24 #include <new>
25 #include "nn/nlib/Config.h"
26 #else
27 #include "nn/nlib/Platform.h"
28 #endif
29 
30 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
31 #undef NLIB_VIS_PUBLIC
32 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
33 #endif
34 
35 #ifndef INCLUDE_NN_NLIB_PLATFORM_H_
36 // some compilers complain about double declaration
37 typedef int errno_t;
38 #endif
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 typedef struct NLIB_VIS_PUBLIC {
45  size_t alloc_count;
46  size_t alloc_size;
47  size_t hash;
48 } HeapHash;
49 
50 typedef struct NLIB_VIS_PUBLIC {
51  void* addr;
52  size_t size;
53  unsigned int heap_option;
55 
56 #define NMALLOC_HEAPOPTION_ENABLE_ENV (0x00000001)
57 #define NMALLOC_HEAPOPTION_CACHE_DISABLE (0x00000004)
58 
59 #ifdef _MSC_VER
60 void nmalloc_get_settings(NMallocSettings* settings); // weak function
61 NLIB_VIS_PUBLIC void nmalloc_get_settings_default(NMallocSettings* settings);
62 #ifndef _WIN64
63 #pragma comment(linker, "/alternatename:_nmalloc_get_settings=_nmalloc_get_settings_default")
64 #else
65 #pragma comment(linker, "/alternatename:nmalloc_get_settings=nmalloc_get_settings_default")
66 #endif
67 #else
68 NLIB_VIS_PUBLIC void nmalloc_get_settings(NMallocSettings* settings); // weak function
69 #endif
70 
71 typedef enum {
77  NMALLOC_DUMP_BASIC = kNmallocDumpBasic,
78  NMALLOC_DUMP_SPANS = kNmallocDumpSpans,
79  NMALLOC_DUMP_POINTERS = kNmallocDumpPointers,
80  NMALLOC_DUMP_PAGESUMMARY = kNmallocDumpPageSummary,
81  NMALLOC_DUMP_ALL = kNmallocDumpAll
83 
84 typedef enum {
85  kNmallocQueryDump = 0,
86  kNmallocQueryPageSize,
87  kNmallocQueryAllocatedSize,
88  kNmallocQueryFreeSize,
89  kNmallocQuerySystemSize,
90  kNmallocQueryMaxAllocatableSize,
91  kNmallocQueryIsClean,
92  kNmallocQueryHeapHash,
93  kNmallocQueryUnifyFreelist,
94  kNmallocQuerySetColor,
95  kNmallocQueryGetColor,
96  kNmallocQuerySetName,
97  kNmallocQueryGetName,
98  kNmallocQueryCacheMin_,
99  kNmallocQueryCheckCache,
100  kNmallocQueryClearCache,
101  kNmallocQueryFinalizeCache,
102  NMALLOC_QUERY_DUMP = kNmallocQueryDump,
103  NMALLOC_QUERY_PAGE_SIZE = kNmallocQueryPageSize,
104  NMALLOC_QUERY_ALLOCATED_SIZE = kNmallocQueryAllocatedSize,
105  NMALLOC_QUERY_FREE_SIZE = kNmallocQueryFreeSize,
106  NMALLOC_QUERY_SYSTEM_SIZE = kNmallocQuerySystemSize,
107  NMALLOC_QUERY_MAX_ALLOCATABLE_SIZE = kNmallocQueryMaxAllocatableSize,
108  NMALLOC_QUERY_IS_CLEAN = kNmallocQueryIsClean,
109  NMALLOC_QUERY_HEAP_HASH = kNmallocQueryHeapHash,
110  NMALLOC_QUERY_UNIFY_FREELIST = kNmallocQueryUnifyFreelist,
111  NMALLOC_QUERY_SET_COLOR = kNmallocQuerySetColor,
112  NMALLOC_QUERY_GET_COLOR = kNmallocQueryGetColor,
113  NMALLOC_QUERY_SET_NAME = kNmallocQuerySetName,
114  NMALLOC_QUERY_GET_NAME = kNmallocQueryGetName,
115  NMALLOC_QUERY_CACHE_MIN_ = kNmallocQueryCacheMin_,
116  NMALLOC_QUERY_CHECK_CACHE = kNmallocQueryCheckCache,
117  NMALLOC_QUERY_CLEAR_CACHE = kNmallocQueryClearCache,
118  NMALLOC_QUERY_FINALIZE_CACHE = kNmallocQueryFinalizeCache
119 } NMallocQuery;
120 
121 typedef int (*nmalloc_heapwalk_callback)(void* allocated_ptr, size_t size, void* user_ptr);
122 
123 NLIB_VIS_PUBLIC errno_t nmalloc_query(int query, ...);
124 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nrealloc(void* ptr, size_t size)
125 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
126 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc(size_t size)
127 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
128 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* ncalloc(size_t nmemb, size_t size)
129 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE2(1, 2) NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
130 NLIB_VIS_PUBLIC NLIB_CHECK_RESULT void* nmalloc_aligned(size_t size, size_t algn)
131 NLIB_ATTRIBUTE_MALLOC NLIB_ATTRIBUTE_ALLOC_SIZE1(1) NLIB_ATTRIBUTE_ALLOC_ALIGN(2)
132 NLIB_ATTRIBUTE_ASSUME_ALIGNED(8);
133 NLIB_VIS_PUBLIC size_t nmalloc_size(const void* ptr) NLIB_NONNULL;
134 NLIB_VIS_PUBLIC void nfree(void* p);
135 NLIB_VIS_PUBLIC void nfree_size(void* p, size_t size);
136 
138 
139 #ifdef __cplusplus
140 }
141 #endif
142 
143 #ifdef __cplusplus
144 
145 inline bool operator==(const HeapHash& rhs, const HeapHash& lhs) {
146  return rhs.alloc_count == lhs.alloc_count && rhs.alloc_size == lhs.alloc_size &&
147  rhs.hash == lhs.hash;
148 }
149 
150 inline bool operator!=(const HeapHash& rhs, const HeapHash& lhs) {
151  return rhs.alloc_count != lhs.alloc_count || rhs.alloc_size != lhs.alloc_size ||
152  rhs.hash != lhs.hash;
153 }
154 
155 NLIB_NAMESPACE_BEGIN
156 namespace heap {
157 
158 template <typename T>
159 struct NMallocStlAllocator {
160  typedef size_t size_type;
161  typedef T value_type;
162  typedef T* pointer;
163  typedef const T* const_pointer;
164  typedef T& reference;
165  typedef const T& const_reference;
166  typedef ptrdiff_t difference_type;
167  template <typename U>
168  struct rebind {
169  typedef NMallocStlAllocator<U> other;
170  };
171  NMallocStlAllocator() {}
172  explicit NMallocStlAllocator(const NMallocStlAllocator<T>&) {}
173  template <class _Other>
174  NMallocStlAllocator(const NMallocStlAllocator<_Other>&) {}
175  pointer allocate(size_type n, const void* p = 0);
176  void deallocate(pointer p, size_type n) {
177 #if 1
178  nfree_size(p, n * sizeof(T));
179 #else
180  (void)n;
181  nfree(p);
182 #endif
183  }
184  void construct(pointer p, const T& t) { new ((void*)p) T(t); } // NOLINT
185  void construct(pointer p) { new ((void*)p) T(); } // NOLINT
186 #if defined(NLIB_CXX11_RVALUE_REFERENCES) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
187  template<class X, class... ARGS>
188  void construct(X* p, ARGS&&... args) {
189  new ((void*)p) X(std::forward<ARGS>(args)...); // NOLINT
190  }
191 #endif
192  void destroy(pointer ptr) {
193  (void)ptr;
194  (*ptr).~T();
195  }
196  template<class X>
197  void destroy(X* p) {
198  NLIB_UNUSED(p); // workaround for VS2012
199  p->~X();
200  }
201  size_t max_size() const {
202  size_t cnt = (size_t)-1 / sizeof(T);
203  return 0 < cnt ? cnt : 1;
204  }
205  pointer address(reference value) const { return &value; }
206  const_pointer address(const_reference value) const { return &value; }
207 };
208 
209 template <typename T>
210 typename NMallocStlAllocator<T>::pointer NMallocStlAllocator<T>::allocate(size_type n,
211  const void* p) {
212  (void)p;
213  void* pp = nmalloc(n * sizeof(T));
214  return reinterpret_cast<T*>(pp);
215 }
216 
217 template <class T1, class T2>
218 inline bool operator==(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
219  return true;
220 }
221 
222 template <class T1, class T2>
223 inline bool operator!=(const NMallocStlAllocator<T1>&, const NMallocStlAllocator<T2>&) {
224  return false;
225 }
226 
227 } // namespace heap
228 NLIB_NAMESPACE_END
229 
230 #endif
231 
232 #ifdef __cplusplus
233 #define NLIB_REPLACE_MALLOC \
234 extern "C" { \
235 void* nlib_malloc(size_t n) { \
236  return nmalloc(n); \
237  } \
238 void nlib_free(void* p) { \
239  nfree(p); \
240  } \
241 void* nlib_calloc(size_t nmemb, size_t size) { \
242  return ncalloc(nmemb, size); \
243  } \
244 void* nlib_realloc(void* ptr, size_t size) { \
245  return nrealloc(ptr, size); \
246  } \
247 void* nlib_memalign(size_t alignment, size_t size) { \
248  return nmalloc_aligned(size, alignment); \
249  } \
250 void nlib_free_size(void* ptr, size_t size) { \
251  nfree_size(ptr, size); \
252  } \
253 }
254 
255 #ifndef NN_PLATFORM_CTR
256 #define NLIB_REPLACE_MALLOC_NEW \
257  NLIB_REPLACE_MALLOC \
258 void* operator new(size_t size) { \
259  return nlib_malloc(size); \
260  } \
261 void operator delete(void* ptr) NLIB_NOEXCEPT { \
262  nlib_free(ptr); \
263  } \
264 void* operator new(size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
265  return nlib_malloc(size); \
266  } \
267 void operator delete(void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { \
268  nlib_free(ptr); \
269  } \
270 void* operator new[](size_t size) { return nlib_malloc(size); } \
271 void operator delete[](void* ptr) NLIB_NOEXCEPT { nlib_free(ptr); } \
272 void* operator new[](size_t size, const std::nothrow_t&) NLIB_NOEXCEPT \
273 { return nlib_malloc(size); } \
274 void operator delete [](void* ptr, const std::nothrow_t&) NLIB_NOEXCEPT { nlib_free(ptr); } \
275 void operator delete(void* ptr, size_t size) NLIB_NOEXCEPT { \
276  nlib_free_size(ptr, size); \
277  } \
278 void operator delete(void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
279  nlib_free_size(ptr, size); \
280  } \
281 void operator delete[](void* ptr, size_t size)NLIB_NOEXCEPT { nlib_free_size(ptr, size); } \
282 void operator delete[](void* ptr, size_t size, const std::nothrow_t&) NLIB_NOEXCEPT { \
283  nlib_free_size(ptr, size); \
284 }
285 #else
286 #define NLIB_REPLACE_MALLOC_NEW \
287  NLIB_REPLACE_MALLOC \
288 void* operator new(size_t size) throw(std::bad_alloc) { \
289  return nlib_malloc(size); \
290  } \
291 void operator delete(void* ptr) throw() { \
292  nlib_free(ptr); \
293  } \
294 void* operator new(size_t size, const std::nothrow_t&) throw() { \
295  return nlib_malloc(size); \
296  } \
297 void* operator new[](size_t size) throw(std::bad_alloc) { \
298  return nlib_malloc(size); \
299  } \
300 void operator delete[](void* ptr) throw() { \
301  nlib_free(ptr); \
302  } \
303 void* operator new[](size_t size, const std::nothrow_t&) throw() { \
304  return nlib_malloc(size); \
305  }
306 #endif
307 #else
308 #define NLIB_REPLACE_MALLOC \
309 void* nlib_malloc(size_t n) { \
310  return nmalloc(n); \
311  } \
312 void nlib_free(void* p) { \
313  nfree(p); \
314  } \
315 void* nlib_calloc(size_t nmemb, size_t size) { \
316  return ncalloc(nmemb, size); \
317  } \
318 void* nlib_realloc(void* ptr, size_t size) { \
319  return nrealloc(ptr, size); \
320  } \
321 void* nlib_memalign(size_t alignment, size_t size) { \
322  return nmalloc_aligned(size, alignment); \
323  } \
324 void nlib_free_size(void* ptr, size_t size) { \
325  nfree_size(ptr, size); \
326  }
327 #define NLIB_REPLACE_MALLOC_NEW NLIB_REPLACE_MALLOC
328 #endif
329 
330 #if defined(_MSC_VER) && defined(nx_heap_EXPORTS)
331 #undef NLIB_VIS_PUBLIC
332 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
333 #endif
334 
335 #endif // INCLUDE_NN_NLIB_HEAP_NMALLOC_H_
void nfree_size(void *p, size_t size)
Frees a memory region. Using information about memory sizes makes it possible to free memory quickly...
#define NLIB_ATTRIBUTE_MALLOC
Defines __attribute__((malloc)) if it is available for use.
int(* nmalloc_heapwalk_callback)(void *allocated_ptr, size_t size, void *user_ptr)
User-defined callback function that is called from nmalloc_walk_allocated_ptrs.
Definition: NMalloc.h:121
Only displays basic information.
Definition: NMalloc.h:72
NLIB_CHECK_RESULT void * nrealloc(void *ptr, size_t size)
Changes the memory allocation. Corresponds to the standard C function realloc.
Displays all information.
Definition: NMalloc.h:76
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
size_t nmalloc_size(const void *ptr)
Returns the amount of memory actually allocated at the ptr parameter.
size_t alloc_size
Total size of the regions allocated by the user application within the heap.
Definition: NMalloc.h:46
Displays the addresses and sizes of all memory allocated by the user application. ...
Definition: NMalloc.h:74
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
Definition: NMalloc.h:145
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
Definition: NMalloc.h:150
errno_t nmalloc_query(int query,...)
Gets and operates detailed data on the heap.
Basic APIs are declared with a C linkage.
NLIB_CHECK_RESULT void * ncalloc(size_t nmemb, size_t size)
Allocates an array of memory and elements initialized to 0.
void nfree(void *p)
Frees a memory region. Corresponds to the standard C function free.
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:89
unsigned int heap_option
Specifies the heap options. The default is 0.
Definition: NMalloc.h:53
size_t alloc_count
Number of regions allocated by the user application within the heap.
Definition: NMalloc.h:45
size_t size
Specifies the maximum amount of memory that can be used by nmalloc. You must specify a multiple of 40...
Definition: NMalloc.h:52
Declares parameters that are initialized by nmalloc. Set by defining nmalloc_get_settings.
Definition: NMalloc.h:50
size_t hash
Hash value of the status of memory allocated by the user application within the heap.
Definition: NMalloc.h:47
NLIB_CHECK_RESULT void * nmalloc(size_t size)
Allocates a memory region of the specified size (in bytes). This corresponds to the standard C functi...
Displays the usage status for each page.
Definition: NMalloc.h:73
A file that contains the configuration information for each development environment.
Visually displays the overview of the page allocation density in the entire heap. An area of 1 MB is ...
Definition: NMalloc.h:75
void * addr
Specifies a pointer to the beginning of the region used by nmalloc.
Definition: NMalloc.h:51
void nmalloc_get_settings(NMallocSettings *settings)
User applications can define this function to control the initialization settings of nmalloc...
errno_t nmalloc_walk_allocated_ptrs(nmalloc_heapwalk_callback func, void *user_ptr)
The callback function func is called for each region allocated in the heap.
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
NMallocDumpMode
The type of the value that you specify for the second argument when specifying kNmallocQueryDump in t...
Definition: NMalloc.h:71
Structure that contains a summary of the memory usage status of the heap used by the user application...
Definition: NMalloc.h:44
NLIB_CHECK_RESULT void * nmalloc_aligned(size_t size, size_t algn)
Allocates memory with a specific alignment.
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37