blob: 76c3fe6cad6697b499b2b044c4adfc499f140491 [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <stdio.h>
2#include <stdlib.h>
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +02003#include <string.h>
Damien429d7192013-10-04 19:53:11 +01004
5#include "misc.h"
Paul Sokolovskyef181022014-01-03 03:06:25 +02006#include "mpconfig.h"
Damien429d7192013-10-04 19:53:11 +01007
Damien George2d15c122014-01-29 20:33:20 +00008#if 0 // print debugging info
Paul Sokolovsky44739e22014-02-16 18:11:42 +02009#define DEBUG_printf DEBUG_printf
Damien George2d15c122014-01-29 20:33:20 +000010#else // don't print debugging info
Damien George1dc76af2014-02-26 16:57:08 +000011#define DEBUG_printf(...) (void)0
Damien George2d15c122014-01-29 20:33:20 +000012#endif
13
Paul Sokolovskyef181022014-01-03 03:06:25 +020014#if MICROPY_MEM_STATS
Paul Sokolovsky520e2f52014-02-12 18:31:30 +020015STATIC int total_bytes_allocated = 0;
16STATIC int current_bytes_allocated = 0;
17STATIC int peak_bytes_allocated = 0;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020018
19#define UPDATE_PEAK() { if (current_bytes_allocated > peak_bytes_allocated) peak_bytes_allocated = current_bytes_allocated; }
Paul Sokolovskyef181022014-01-03 03:06:25 +020020#endif
Damien429d7192013-10-04 19:53:11 +010021
Paul Sokolovskyb62c30b2014-02-10 22:37:09 +020022#if MICROPY_ENABLE_GC
23#include "gc.h"
24
25// We redirect standard alloc functions to GC heap - just for the rest of
26// this module. In the rest of micropython source, system malloc can be
27// freely accessed - for interfacing with system and 3rd-party libs for
28// example. On the other hand, some (e.g. bare-metal) ports may use GC
29// heap as system heap, so, to avoid warnings, we do undef's first.
30#undef malloc
31#undef free
32#undef realloc
Damien George12bab722014-04-05 20:35:48 +010033#define malloc(b) gc_alloc((b), false)
34#define malloc_with_finaliser(b) gc_alloc((b), true)
Paul Sokolovskyb62c30b2014-02-10 22:37:09 +020035#define free gc_free
36#define realloc gc_realloc
37#endif // MICROPY_ENABLE_GC
38
Damien429d7192013-10-04 19:53:11 +010039void *m_malloc(int num_bytes) {
40 if (num_bytes == 0) {
41 return NULL;
42 }
43 void *ptr = malloc(num_bytes);
44 if (ptr == NULL) {
Damien George6902eed2014-04-04 10:52:59 +000045 return m_malloc_fail(num_bytes);
Damien429d7192013-10-04 19:53:11 +010046 }
Paul Sokolovskyef181022014-01-03 03:06:25 +020047#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +010048 total_bytes_allocated += num_bytes;
Paul Sokolovsky02de0c52014-01-01 23:15:47 +020049 current_bytes_allocated += num_bytes;
Paul Sokolovsky780f5552014-01-01 23:42:21 +020050 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +020051#endif
Damien George2d15c122014-01-29 20:33:20 +000052 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
Damien429d7192013-10-04 19:53:11 +010053 return ptr;
54}
55
Damien Georgef0954e32014-04-10 14:38:25 +010056void *m_malloc_maybe(int num_bytes) {
57 void *ptr = malloc(num_bytes);
58 if (ptr == NULL) {
59 return NULL;
60 }
61#if MICROPY_MEM_STATS
62 total_bytes_allocated += num_bytes;
63 current_bytes_allocated += num_bytes;
64 UPDATE_PEAK();
65#endif
66 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
67 return ptr;
68}
69
Damien George12bab722014-04-05 20:35:48 +010070#if MICROPY_ENABLE_FINALISER
71void *m_malloc_with_finaliser(int num_bytes) {
mux4f7e9f52014-04-03 23:55:12 +020072 if (num_bytes == 0) {
73 return NULL;
74 }
Damien George12bab722014-04-05 20:35:48 +010075 void *ptr = malloc_with_finaliser(num_bytes);
mux4f7e9f52014-04-03 23:55:12 +020076 if (ptr == NULL) {
Damien George12bab722014-04-05 20:35:48 +010077 return m_malloc_fail(num_bytes);
mux4f7e9f52014-04-03 23:55:12 +020078 }
79#if MICROPY_MEM_STATS
80 total_bytes_allocated += num_bytes;
81 current_bytes_allocated += num_bytes;
82 UPDATE_PEAK();
83#endif
84 DEBUG_printf("malloc %d : %p\n", num_bytes, ptr);
85 return ptr;
86}
Damien George12bab722014-04-05 20:35:48 +010087#endif
mux4f7e9f52014-04-03 23:55:12 +020088
Damien429d7192013-10-04 19:53:11 +010089void *m_malloc0(int num_bytes) {
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +020090 void *ptr = m_malloc(num_bytes);
Damien Georgedaab6512014-04-25 23:37:55 +010091#if MICROPY_ENABLE_GC
92 // the GC already zeros out all memory
93#else
Paul Sokolovsky58ff93b2014-02-10 18:37:11 +020094 if (ptr != NULL) {
95 memset(ptr, 0, num_bytes);
Damien429d7192013-10-04 19:53:11 +010096 }
Damien Georgedaab6512014-04-25 23:37:55 +010097#endif
Damien429d7192013-10-04 19:53:11 +010098 return ptr;
99}
100
Damien732407f2013-12-29 19:33:23 +0000101void *m_realloc(void *ptr, int old_num_bytes, int new_num_bytes) {
102 if (new_num_bytes == 0) {
Damien429d7192013-10-04 19:53:11 +0100103 free(ptr);
104 return NULL;
105 }
Paul Sokolovskycdd2c622014-01-30 03:58:17 +0200106 void *new_ptr = realloc(ptr, new_num_bytes);
107 if (new_ptr == NULL) {
Damien George6902eed2014-04-04 10:52:59 +0000108 return m_malloc_fail(new_num_bytes);
Damien429d7192013-10-04 19:53:11 +0100109 }
Paul Sokolovskyef181022014-01-03 03:06:25 +0200110#if MICROPY_MEM_STATS
Paul Sokolovsky43f1c802014-01-01 23:04:25 +0200111 // At first thought, "Total bytes allocated" should only grow,
112 // after all, it's *total*. But consider for example 2K block
113 // shrunk to 1K and then grown to 2K again. It's still 2K
114 // allocated total. If we process only positive increments,
115 // we'll count 3K.
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200116 int diff = new_num_bytes - old_num_bytes;
117 total_bytes_allocated += diff;
118 current_bytes_allocated += diff;
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200119 UPDATE_PEAK();
Paul Sokolovskyef181022014-01-03 03:06:25 +0200120#endif
Paul Sokolovskycdd2c622014-01-30 03:58:17 +0200121 DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
122 return new_ptr;
Damien429d7192013-10-04 19:53:11 +0100123}
124
Damien George58ba4c32014-04-10 14:27:31 +0000125void *m_realloc_maybe(void *ptr, int old_num_bytes, int new_num_bytes) {
126 void *new_ptr = realloc(ptr, new_num_bytes);
127 if (new_ptr == NULL) {
128 return NULL;
129 }
130#if MICROPY_MEM_STATS
131 // At first thought, "Total bytes allocated" should only grow,
132 // after all, it's *total*. But consider for example 2K block
133 // shrunk to 1K and then grown to 2K again. It's still 2K
134 // allocated total. If we process only positive increments,
135 // we'll count 3K.
136 int diff = new_num_bytes - old_num_bytes;
137 total_bytes_allocated += diff;
138 current_bytes_allocated += diff;
139 UPDATE_PEAK();
140#endif
141 DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
142 return new_ptr;
143}
144
Damien732407f2013-12-29 19:33:23 +0000145void m_free(void *ptr, int num_bytes) {
146 if (ptr != NULL) {
147 free(ptr);
148 }
Paul Sokolovskyef181022014-01-03 03:06:25 +0200149#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200150 current_bytes_allocated -= num_bytes;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200151#endif
Damien George2d15c122014-01-29 20:33:20 +0000152 DEBUG_printf("free %p, %d\n", ptr, num_bytes);
Damien732407f2013-12-29 19:33:23 +0000153}
154
Damien8b3a7c22013-10-23 20:20:17 +0100155int m_get_total_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200156#if MICROPY_MEM_STATS
Damien429d7192013-10-04 19:53:11 +0100157 return total_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200158#else
159 return -1;
160#endif
Damien429d7192013-10-04 19:53:11 +0100161}
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200162
163int m_get_current_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200164#if MICROPY_MEM_STATS
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200165 return current_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200166#else
167 return -1;
168#endif
Paul Sokolovsky02de0c52014-01-01 23:15:47 +0200169}
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200170
171int m_get_peak_bytes_allocated(void) {
Paul Sokolovskyef181022014-01-03 03:06:25 +0200172#if MICROPY_MEM_STATS
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200173 return peak_bytes_allocated;
Paul Sokolovskyef181022014-01-03 03:06:25 +0200174#else
175 return -1;
176#endif
Paul Sokolovsky780f5552014-01-01 23:42:21 +0200177}