mirror of https://github.com/arendst/Tasmota.git
Berry stores compiled bytecode into IRAM, freeing space in heap
This commit is contained in:
parent
304e13911c
commit
6755b754e0
|
@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
|
|||
- PubSubClient library from v2.8.12 to v2.8.13
|
||||
- From Semantic Versioning (SemVer) to Calendar Versioning (CalVer)
|
||||
- Set ESP32 stack size with ``#define SET_ESP32_STACK_SIZE``, added ``StackLowMark`` metrics
|
||||
- Berry stores compiled bytecode into IRAM, freeing space in heap
|
||||
|
||||
### Fixed
|
||||
- Intermittent exceptions and heap corruption due to PubSubClient library buffer overflow (#13700)
|
||||
|
|
|
@ -214,6 +214,9 @@ extern "C" {
|
|||
extern void *berry_malloc(size_t size);
|
||||
extern void berry_free(void *ptr);
|
||||
extern void *berry_realloc(void *ptr, size_t size);
|
||||
extern void *berry_malloc32(size_t size);
|
||||
extern void berry_free32(void *ptr);
|
||||
extern void *berry_realloc32(void *ptr, size_t size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -241,7 +244,7 @@ extern "C" {
|
|||
/* Tasmota debug specific */
|
||||
#ifdef USE_BERRY_DEBUG
|
||||
#undef BE_DEBUG_RUNTIME_INFO
|
||||
#define BE_DEBUG_RUNTIME_INFO 2 /* record line information in 16 bits */
|
||||
#define BE_DEBUG_RUNTIME_INFO 1 /* record line information in 32 bits to be places in IRAM */
|
||||
#endif // USE_BERRY_DEBUG
|
||||
|
||||
#endif
|
||||
|
|
|
@ -313,14 +313,14 @@ static void end_func(bparser *parser)
|
|||
be_code_ret(finfo, NULL); /* append a return to last code */
|
||||
end_block(parser); /* close block */
|
||||
setupvals(finfo); /* close upvals */
|
||||
proto->code = be_vector_release(vm, &finfo->code); /* compact all vectors and return NULL if empty */
|
||||
proto->code = be_vector_release_32(vm, &finfo->code); /* compact all vectors and return NULL if empty */
|
||||
proto->codesize = finfo->pc;
|
||||
proto->ktab = be_vector_release(vm, &finfo->kvec);
|
||||
proto->ktab = be_vector_release_32(vm, &finfo->kvec);
|
||||
proto->nconst = be_vector_count(&finfo->kvec);
|
||||
proto->ptab = be_vector_release(vm, &finfo->pvec);
|
||||
proto->nproto = be_vector_count(&finfo->pvec);
|
||||
#if BE_DEBUG_RUNTIME_INFO
|
||||
proto->lineinfo = be_vector_release(vm, &finfo->linevec);
|
||||
proto->lineinfo = be_vector_release_32(vm, &finfo->linevec);
|
||||
proto->nlineinfo = be_vector_count(&finfo->linevec);
|
||||
#endif
|
||||
#if BE_DEBUG_VAR_INFO
|
||||
|
|
|
@ -110,6 +110,32 @@ void* be_vector_release(bvm *vm, bvector *vector)
|
|||
return vector->data;
|
||||
}
|
||||
|
||||
/* free not used */
|
||||
void* be_vector_release_32(bvm *vm, bvector *vector)
|
||||
{
|
||||
size_t size = vector->size;
|
||||
int count = be_vector_count(vector);
|
||||
if (count == 0) {
|
||||
be_free(vm, vector->data, vector->capacity * size);
|
||||
vector->capacity = 0;
|
||||
vector->data = NULL;
|
||||
vector->end = NULL;
|
||||
} else if (count < vector->capacity) {
|
||||
vector->data = be_realloc(vm,
|
||||
vector->data, vector->capacity * size, count * size); // TODO - can we skip that step?
|
||||
void* iram = berry_malloc32(count * size);
|
||||
if (iram) {
|
||||
memcpy(iram, vector->data, count * size);
|
||||
free(vector->data);
|
||||
vector->data = iram;
|
||||
}
|
||||
// vm->gc.usage = vm->gc.usage + count * size - vector->capacity * size; /* update allocated count */
|
||||
vector->end = (char*)vector->data + ((size_t)count - 1) * size;
|
||||
vector->capacity = count;
|
||||
}
|
||||
return vector->data;
|
||||
}
|
||||
|
||||
/* use binary search to find the vector capacity between 0-1024 */
|
||||
static int binary_search(int value)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ void be_vector_remove_end(bvector *vector);
|
|||
void be_vector_resize(bvm *vm, bvector *vector, int count);
|
||||
void be_vector_clear(bvector *vector);
|
||||
void* be_vector_release(bvm *vm, bvector *vector);
|
||||
void* be_vector_release_32(bvm *vm, bvector *vector); /* specialized call for 32 bits aligned accesses */
|
||||
int be_nextsize(int value);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1009,6 +1009,7 @@
|
|||
#define USE_BERRY_PYTHON_COMPAT // Enable by default `import python_compat`
|
||||
#define USE_BERRY_TIMEOUT 4000 // Timeout in ms, will raise an exception if running time exceeds this timeout
|
||||
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
||||
#define USE_BERRY_IRAM // Allocate some data structures in IRAM (which is ususally unused) when possible and if no PSRAM is available
|
||||
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
|
||||
#define USE_WEBCLIENT // Enable `webclient` to make HTTP/HTTPS requests. Can be disabled for security reasons.
|
||||
// #define USE_WEBCLIENT_HTTPS // Enable HTTPS outgoing requests based on BearSSL (much ligher then mbedTLS, 42KB vs 150KB) in insecure mode (no verification of server's certificate)
|
||||
|
|
|
@ -503,6 +503,17 @@ void *special_calloc(size_t num, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
// Variants for IRAM heap, which need all accesses to be 32 bits aligned
|
||||
void *special_malloc32(uint32_t size) {
|
||||
return heap_caps_malloc(size, UsePSRAM() ? MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT : MALLOC_CAP_32BIT);
|
||||
}
|
||||
void *special_realloc32(void *ptr, size_t size) {
|
||||
return heap_caps_realloc(ptr, size, UsePSRAM() ? MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT : MALLOC_CAP_32BIT);
|
||||
}
|
||||
void *special_calloc32(size_t num, size_t size) {
|
||||
return heap_caps_calloc(num, size, UsePSRAM() ? MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT : MALLOC_CAP_32BIT);
|
||||
}
|
||||
|
||||
float CpuTemperature(void) {
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
return (float)temperatureRead(); // In Celsius
|
||||
|
|
|
@ -84,6 +84,29 @@ extern "C" {
|
|||
}
|
||||
#endif // USE_BERRY_PSRAM
|
||||
|
||||
|
||||
void *berry_malloc32(uint32_t size) {
|
||||
#ifdef USE_BERRY_IRAM
|
||||
return special_malloc32(size);
|
||||
#else
|
||||
return special_malloc(size);
|
||||
#endif
|
||||
}
|
||||
void *berry_realloc32(void *ptr, size_t size) {
|
||||
#ifdef USE_BERRY_IRAM
|
||||
return special_realloc32(ptr, size);
|
||||
#else
|
||||
return special_realloc(ptr, size);
|
||||
#endif
|
||||
}
|
||||
void *berry_calloc32(size_t num, size_t size) {
|
||||
#ifdef USE_BERRY_IRAM
|
||||
return special_calloc32(num, size);
|
||||
#else
|
||||
return special_calloc(num, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void berry_free(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue