|
27 | 27 |
|
28 | 28 | #include <string.h>
|
29 | 29 |
|
| 30 | +#ifdef TJS__HAS_MIMALLOC |
| 31 | +#include <mimalloc.h> |
| 32 | +#endif |
30 | 33 |
|
31 | 34 | #define TJS__DEFAULT_STACK_SIZE 1048576
|
32 | 35 |
|
| 36 | +static inline size_t tjs__malloc_usable_size(const void *ptr) { |
| 37 | +#if defined(TJS__HAS_MIMALLOC) |
| 38 | + return mi_malloc_usable_size(ptr); |
| 39 | +#elif defined(__APPLE__) |
| 40 | + return malloc_size(ptr); |
| 41 | +#elif defined(_WIN32) |
| 42 | + return _msize(ptr); |
| 43 | +#elif defined(__linux__) || defined (__CYGWIN__) |
| 44 | + return malloc_usable_size(ptr); |
| 45 | +#else |
| 46 | + // Unknown. |
| 47 | + return 0; |
| 48 | +#endif |
| 49 | +} |
| 50 | + |
| 51 | +static inline void *tjs__malloc(size_t size) { |
| 52 | +#ifdef TJS__HAS_MIMALLOC |
| 53 | + return mi_malloc(size); |
| 54 | +#else |
| 55 | + return malloc(size); |
| 56 | +#endif |
| 57 | +} |
| 58 | + |
| 59 | +static inline void *tjs__calloc(size_t count, size_t size) { |
| 60 | +#ifdef TJS__HAS_MIMALLOC |
| 61 | + return mi_calloc(count, size); |
| 62 | +#else |
| 63 | + return calloc(count, size); |
| 64 | +#endif |
| 65 | +} |
| 66 | + |
| 67 | +static inline void tjs__free(void *ptr) { |
| 68 | +#ifdef TJS__HAS_MIMALLOC |
| 69 | + mi_free(ptr); |
| 70 | +#else |
| 71 | + free(ptr); |
| 72 | +#endif |
| 73 | +} |
| 74 | + |
| 75 | +static inline void *tjs__realloc(void *ptr, size_t size) { |
| 76 | +#ifdef TJS__HAS_MIMALLOC |
| 77 | + return mi_realloc(ptr, size); |
| 78 | +#else |
| 79 | + return realloc(ptr, size); |
| 80 | +#endif |
| 81 | +} |
| 82 | + |
| 83 | +static void *tjs__mf_malloc(JSMallocState *s, size_t size) { |
| 84 | + void *ptr; |
| 85 | + |
| 86 | + /* Do not allocate zero bytes: behavior is platform dependent */ |
| 87 | + assert(size != 0); |
| 88 | + |
| 89 | + if (unlikely(s->malloc_size + size > s->malloc_limit)) |
| 90 | + return NULL; |
| 91 | + |
| 92 | + ptr = tjs__malloc(size); |
| 93 | + if (!ptr) |
| 94 | + return NULL; |
| 95 | + |
| 96 | + s->malloc_count++; |
| 97 | + s->malloc_size += tjs__malloc_usable_size(ptr); |
| 98 | + return ptr; |
| 99 | +} |
| 100 | + |
| 101 | +static void tjs__mf_free(JSMallocState *s, void *ptr) { |
| 102 | + if (!ptr) |
| 103 | + return; |
| 104 | + |
| 105 | + s->malloc_count--; |
| 106 | + s->malloc_size -= tjs__malloc_usable_size(ptr); |
| 107 | + tjs__free(ptr); |
| 108 | +} |
| 109 | + |
| 110 | +static void *tjs__mf_realloc(JSMallocState *s, void *ptr, size_t size) { |
| 111 | + size_t old_size; |
| 112 | + |
| 113 | + if (!ptr) { |
| 114 | + if (size == 0) |
| 115 | + return NULL; |
| 116 | + return tjs__mf_malloc(s, size); |
| 117 | + } |
| 118 | + old_size = tjs__malloc_usable_size(ptr); |
| 119 | + if (size == 0) { |
| 120 | + s->malloc_count--; |
| 121 | + s->malloc_size -= old_size; |
| 122 | + tjs__free(ptr); |
| 123 | + return NULL; |
| 124 | + } |
| 125 | + if (s->malloc_size + size - old_size > s->malloc_limit) |
| 126 | + return NULL; |
| 127 | + |
| 128 | + ptr = tjs__realloc(ptr, size); |
| 129 | + if (!ptr) |
| 130 | + return NULL; |
| 131 | + |
| 132 | + s->malloc_size += tjs__malloc_usable_size(ptr) - old_size; |
| 133 | + return ptr; |
| 134 | +} |
| 135 | + |
| 136 | +static const JSMallocFunctions tjs_mf = { |
| 137 | + tjs__mf_malloc, |
| 138 | + tjs__mf_free, |
| 139 | + tjs__mf_realloc, |
| 140 | + tjs__malloc_usable_size |
| 141 | +}; |
| 142 | + |
33 | 143 | /* core */
|
34 | 144 | extern const uint8_t tjs__core[];
|
35 | 145 | extern const uint32_t tjs__core_size;
|
@@ -157,11 +267,11 @@ TJSRuntime *TJS_NewRuntimeWorker(void) {
|
157 | 267 | }
|
158 | 268 |
|
159 | 269 | TJSRuntime *TJS_NewRuntimeInternal(bool is_worker, TJSRunOptions *options) {
|
160 |
| - TJSRuntime *qrt = calloc(1, sizeof(*qrt)); |
| 270 | + TJSRuntime *qrt = tjs__calloc(1, sizeof(*qrt)); |
161 | 271 |
|
162 | 272 | memcpy(&qrt->options, options, sizeof(*options));
|
163 | 273 |
|
164 |
| - qrt->rt = JS_NewRuntime(); |
| 274 | + qrt->rt = JS_NewRuntime2(&tjs_mf, NULL); |
165 | 275 | CHECK_NOT_NULL(qrt->rt);
|
166 | 276 |
|
167 | 277 | qrt->ctx = JS_NewContext(qrt->rt);
|
@@ -279,12 +389,14 @@ void TJS_FreeRuntime(TJSRuntime *qrt) {
|
279 | 389 | JS_FreeRuntime(qrt->rt);
|
280 | 390 | qrt->rt = NULL;
|
281 | 391 |
|
282 |
| - free(qrt); |
| 392 | + tjs__free(qrt); |
283 | 393 | }
|
284 | 394 |
|
285 | 395 | void TJS_Initialize(int argc, char **argv) {
|
286 | 396 | curl_global_init(CURL_GLOBAL_ALL);
|
287 | 397 |
|
| 398 | + CHECK_EQ(0, uv_replace_allocator(tjs__malloc, tjs__realloc, tjs__calloc, tjs__free)); |
| 399 | + |
288 | 400 | tjs__argc = argc;
|
289 | 401 | tjs__argv = uv_setup_args(argc, argv);
|
290 | 402 | }
|
|
0 commit comments