Merge pull request #15338 from s-hadinger/berry_stack_resize

Berry stack resize debug mode
This commit is contained in:
Theo Arends 2022-04-13 15:12:09 +02:00 committed by GitHub
commit 942c2e9806
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 5 deletions

View File

@ -175,6 +175,14 @@
**/
#define BE_USE_DEBUG_GC 0
/* Macro: BE_USE_DEBUG_STACK
* Enable Stack Resize debug mode. At each function call
* the stack is reallocated at a different memory location
* and the previous location is cleared with toxic data.
* Default: 0
**/
#define BE_USE_DEBUG_STACK 0
/* Macro: BE_USE_MEM_ALIGNED
* Some embedded processors have special memory areas
* with read/write constraints of being aligned to 32 bits boundaries.

View File

@ -15,6 +15,7 @@
#include "be_bytecode.h"
#include "be_decoder.h"
#include <stdlib.h>
#include <string.h>
#if !BE_USE_SCRIPT_COMPILER && !BE_USE_BYTECODE_LOADER
#error no compiler or bytecode loader enabled.
@ -337,9 +338,13 @@ void be_stackpush(bvm *vm)
/* check that the stack is able to store `count` items, and increase stack if needed */
BERRY_API void be_stack_require(bvm *vm, int count)
{
#if BE_USE_DEBUG_STACK == 0
if (vm->top + count >= vm->stacktop) {
be_stack_expansion(vm, count);
}
#else
be_stack_expansion(vm, vm->top - vm->stacktop + count); /* force exact resize each time */
#endif
}
/* Scan the entire callstack and adjust all pointer by `offset` */
@ -372,7 +377,16 @@ static void stack_resize(bvm *vm, size_t size)
intptr_t offset;
bvalue *old = vm->stack; /* save original pointer of stack before resize */
size_t os = (vm->stacktop - old) * sizeof(bvalue); /* size of current stack allocated in bytes */
#if BE_USE_DEBUG_STACK == 0
vm->stack = be_realloc(vm, old, os, sizeof(bvalue) * size); /* reallocate with the new size */
#else /* force a reallocation */
size_t ns = sizeof(bvalue) * size;
vm->stack = be_malloc(vm, ns);
size_t transf = (os < ns) ? os : ns; /* min size */
memmove(vm->stack, old, transf); /* copy to new location */
memset(old, 0xFF, os); /* fill the structure with invalid pointers */
be_free(vm, old, os);
#endif
vm->stacktop = vm->stack + size; /* compute new stacktop */
offset = ptr_offset(vm->stack, old); /* compute the address difference between old and ne stack addresses */
/* update callframes */
@ -386,7 +400,7 @@ static void stack_resize(bvm *vm, size_t size)
/* Check if we are above the max allowed stack */
void be_stack_expansion(bvm *vm, int n)
{
size_t size = vm->stacktop - vm->stack;
int size = vm->stacktop - vm->stack; /* with debug enabled, stack increase may be negative */
/* check new stack size */
if (size + n > BE_STACK_TOTAL_MAX) {
/* ensure the stack is enough when generating error messages. */

View File

@ -1207,11 +1207,12 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
for (v = vm->reg + argc; v <= end; ++v) {
var_setnil(v);
}
int v_offset = v - vm->stack; /* offset from stack base, stack may be reallocated */
if (proto->varg & BE_VA_VARARG) { /* there are vararg at the last argument, build the list */
/* code below uses mostly low-level calls for performance */
be_stack_require(vm, argc + 2); /* make sure we don't overflow the stack */
bvalue *top_save = vm->top; /* save original stack, we need fresh slots to create the 'list' instance */
vm->top = v; /* move top of stack right after last argument */
be_stack_require(vm, argc + 4); /* make sure we don't overflow the stack */
int top_save_offset = vm->top - vm->stack; /* save original stack, we need fresh slots to create the 'list' instance */
vm->top = vm->stack + v_offset; /* move top of stack right after last argument */
be_newobject(vm, "list"); /* this creates 2 objects on stack: list instance, BE_LIST object */
blist *list = var_toobj(vm->top-1); /* get low-level BE_LIST structure */
v = vm->reg + proto->argc - 1; /* last argument */
@ -1219,7 +1220,7 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
be_list_push(vm, list, v); /* push all varargs into list */
}
*(vm->reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */
vm->top = top_save; /* restore top of stack pointer */
vm->top = vm->stack + top_save_offset; /* restore top of stack pointer */
}
}