mem_alloc.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "mem_alloc.h"
  6. #include <stdbool.h>
  7. #if DEFAULT_MEM_ALLOCATOR == MEM_ALLOCATOR_EMS
  8. #include "ems/ems_gc.h"
  9. mem_allocator_t
  10. mem_allocator_create(void *mem, uint32_t size)
  11. {
  12. return gc_init_with_pool((char *)mem, size);
  13. }
  14. mem_allocator_t
  15. mem_allocator_create_with_struct_and_pool(void *struct_buf,
  16. uint32_t struct_buf_size,
  17. void *pool_buf,
  18. uint32_t pool_buf_size)
  19. {
  20. return gc_init_with_struct_and_pool((char *)struct_buf, struct_buf_size,
  21. pool_buf, pool_buf_size);
  22. }
  23. int
  24. mem_allocator_destroy(mem_allocator_t allocator)
  25. {
  26. return gc_destroy_with_pool((gc_handle_t)allocator);
  27. }
  28. uint32
  29. mem_allocator_get_heap_struct_size()
  30. {
  31. return gc_get_heap_struct_size();
  32. }
  33. void *
  34. mem_allocator_malloc(mem_allocator_t allocator, uint32_t size)
  35. {
  36. return gc_alloc_vo((gc_handle_t)allocator, size);
  37. }
  38. void *
  39. mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size)
  40. {
  41. return gc_realloc_vo((gc_handle_t)allocator, ptr, size);
  42. }
  43. void
  44. mem_allocator_free(mem_allocator_t allocator, void *ptr)
  45. {
  46. if (ptr)
  47. gc_free_vo((gc_handle_t)allocator, ptr);
  48. }
  49. #if BH_ENABLE_GC_VERIFY == 0
  50. void *
  51. mem_allocator_malloc_aligned(mem_allocator_t allocator, uint32_t size,
  52. uint32_t alignment)
  53. {
  54. return gc_alloc_vo_aligned((gc_handle_t)allocator, size, alignment);
  55. }
  56. #else
  57. void *
  58. mem_allocator_malloc_aligned_internal(mem_allocator_t allocator, uint32_t size,
  59. uint32_t alignment, const char *file,
  60. int line)
  61. {
  62. return gc_alloc_vo_aligned_internal((gc_handle_t)allocator, size, alignment,
  63. file, line);
  64. }
  65. #endif
  66. #if WASM_ENABLE_GC != 0
  67. void *
  68. mem_allocator_malloc_with_gc(mem_allocator_t allocator, uint32_t size)
  69. {
  70. return gc_alloc_wo((gc_handle_t)allocator, size);
  71. }
  72. #if WASM_GC_MANUALLY != 0
  73. void
  74. mem_allocator_free_with_gc(mem_allocator_t allocator, void *ptr)
  75. {
  76. if (ptr)
  77. gc_free_wo((gc_handle_t)allocator, ptr);
  78. }
  79. #endif
  80. #if WASM_ENABLE_THREAD_MGR == 0
  81. void
  82. mem_allocator_enable_gc_reclaim(mem_allocator_t allocator, void *exec_env)
  83. {
  84. gc_enable_gc_reclaim((gc_handle_t)allocator, exec_env);
  85. }
  86. #else
  87. void
  88. mem_allocator_enable_gc_reclaim(mem_allocator_t allocator, void *cluster)
  89. {
  90. gc_enable_gc_reclaim((gc_handle_t)allocator, cluster);
  91. }
  92. #endif
  93. int
  94. mem_allocator_add_root(mem_allocator_t allocator, WASMObjectRef obj)
  95. {
  96. return gc_add_root((gc_handle_t)allocator, (gc_object_t)obj);
  97. }
  98. #endif
  99. int
  100. mem_allocator_migrate(mem_allocator_t allocator, char *pool_buf_new,
  101. uint32 pool_buf_size)
  102. {
  103. return gc_migrate((gc_handle_t)allocator, pool_buf_new, pool_buf_size);
  104. }
  105. bool
  106. mem_allocator_is_heap_corrupted(mem_allocator_t allocator)
  107. {
  108. return gc_is_heap_corrupted((gc_handle_t)allocator);
  109. }
  110. bool
  111. mem_allocator_get_alloc_info(mem_allocator_t allocator, void *mem_alloc_info)
  112. {
  113. gc_heap_stats((gc_handle_t)allocator, mem_alloc_info, 3);
  114. return true;
  115. }
  116. #if WASM_ENABLE_GC != 0
  117. bool
  118. mem_allocator_set_gc_finalizer(mem_allocator_t allocator, void *obj,
  119. gc_finalizer_t cb, void *data)
  120. {
  121. return gc_set_finalizer((gc_handle_t)allocator, (gc_object_t)obj, cb, data);
  122. }
  123. void
  124. mem_allocator_unset_gc_finalizer(mem_allocator_t allocator, void *obj)
  125. {
  126. gc_unset_finalizer((gc_handle_t)allocator, (gc_object_t)obj);
  127. }
  128. #if WASM_ENABLE_GC_PERF_PROFILING != 0
  129. void
  130. mem_allocator_dump_perf_profiling(mem_allocator_t allocator)
  131. {
  132. gc_dump_perf_profiling((gc_handle_t)allocator);
  133. }
  134. #endif
  135. #endif
  136. #else /* else of DEFAULT_MEM_ALLOCATOR */
  137. #include "tlsf/tlsf.h"
  138. typedef struct mem_allocator_tlsf {
  139. tlsf_t tlsf;
  140. korp_mutex lock;
  141. } mem_allocator_tlsf;
  142. mem_allocator_t
  143. mem_allocator_create(void *mem, uint32_t size)
  144. {
  145. mem_allocator_tlsf *allocator_tlsf;
  146. tlsf_t tlsf;
  147. char *mem_aligned = (char *)(((uintptr_t)mem + 3) & ~3);
  148. if (size < 1024) {
  149. printf("Create mem allocator failed: pool size must be "
  150. "at least 1024 bytes.\n");
  151. return NULL;
  152. }
  153. size -= mem_aligned - (char *)mem;
  154. mem = (void *)mem_aligned;
  155. tlsf = tlsf_create_with_pool(mem, size);
  156. if (!tlsf) {
  157. printf("Create mem allocator failed: tlsf_create_with_pool failed.\n");
  158. return NULL;
  159. }
  160. allocator_tlsf = tlsf_malloc(tlsf, sizeof(mem_allocator_tlsf));
  161. if (!allocator_tlsf) {
  162. printf("Create mem allocator failed: tlsf_malloc failed.\n");
  163. tlsf_destroy(tlsf);
  164. return NULL;
  165. }
  166. allocator_tlsf->tlsf = tlsf;
  167. if (os_mutex_init(&allocator_tlsf->lock)) {
  168. printf("Create mem allocator failed: tlsf_malloc failed.\n");
  169. tlsf_free(tlsf, allocator_tlsf);
  170. tlsf_destroy(tlsf);
  171. return NULL;
  172. }
  173. return allocator_tlsf;
  174. }
  175. void
  176. mem_allocator_destroy(mem_allocator_t allocator)
  177. {
  178. mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
  179. tlsf_t tlsf = allocator_tlsf->tlsf;
  180. os_mutex_destroy(&allocator_tlsf->lock);
  181. tlsf_free(tlsf, allocator_tlsf);
  182. tlsf_destroy(tlsf);
  183. }
  184. void *
  185. mem_allocator_malloc(mem_allocator_t allocator, uint32_t size)
  186. {
  187. void *ret;
  188. mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
  189. if (size == 0)
  190. /* tlsf doesn't allow to allocate 0 byte */
  191. size = 1;
  192. os_mutex_lock(&allocator_tlsf->lock);
  193. ret = tlsf_malloc(allocator_tlsf->tlsf, size);
  194. os_mutex_unlock(&allocator_tlsf->lock);
  195. return ret;
  196. }
  197. void *
  198. mem_allocator_realloc(mem_allocator_t allocator, void *ptr, uint32_t size)
  199. {
  200. void *ret;
  201. mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
  202. if (size == 0)
  203. /* tlsf doesn't allow to allocate 0 byte */
  204. size = 1;
  205. os_mutex_lock(&allocator_tlsf->lock);
  206. ret = tlsf_realloc(allocator_tlsf->tlsf, ptr, size);
  207. os_mutex_unlock(&allocator_tlsf->lock);
  208. return ret;
  209. }
  210. void
  211. mem_allocator_free(mem_allocator_t allocator, void *ptr)
  212. {
  213. if (ptr) {
  214. mem_allocator_tlsf *allocator_tlsf = (mem_allocator_tlsf *)allocator;
  215. os_mutex_lock(&allocator_tlsf->lock);
  216. tlsf_free(allocator_tlsf->tlsf, ptr);
  217. os_mutex_unlock(&allocator_tlsf->lock);
  218. }
  219. }
  220. int
  221. mem_allocator_migrate(mem_allocator_t allocator, mem_allocator_t allocator_old)
  222. {
  223. return tlsf_migrate((mem_allocator_tlsf *)allocator,
  224. (mem_allocator_tlsf *)allocator_old);
  225. }
  226. #endif /* end of DEFAULT_MEM_ALLOCATOR */