diff --git a/src/c/interpreter.d b/src/c/interpreter.d index 7e9fdd205..bcf5668ad 100644 --- a/src/c/interpreter.d +++ b/src/c/interpreter.d @@ -26,35 +26,31 @@ void cl_stack_set_size(cl_index tentative_new_size) { cl_index top = cl_env.stack_top - cl_env.stack; - cl_object *new_stack; + cl_object *new_stack, *old_stack; cl_index safety_area = ecl_get_option(ECL_OPT_LISP_STACK_SAFETY_AREA); cl_index new_size = tentative_new_size + 2*safety_area; if (top > new_size) FEerror("Internal error: cannot shrink stack that much.",0); - start_critical_section(); - + old_stack = cl_env.stack; new_stack = (cl_object *)ecl_alloc_atomic(new_size * sizeof(cl_object)); - memcpy(new_stack, cl_env.stack, cl_env.stack_size * sizeof(cl_object)); -#ifdef BOEHM_GBC - GC_free(cl_env.stack); -#else - cl_dealloc(cl_env.stack); -#endif + ecl_disable_interrupts(); + memcpy(new_stack, old_stack, cl_env.stack_size * sizeof(cl_object)); cl_env.stack_size = new_size; cl_env.stack = new_stack; cl_env.stack_top = cl_env.stack + top; cl_env.stack_limit = cl_env.stack + (new_size - 2*safety_area); + ecl_enable_interrupts(); + + cl_dealloc(old_stack); /* A stack always has at least one element. This is assumed by cl__va_start * and friends, which take a sp=0 to have no arguments. */ if (top == 0) cl_stack_push(MAKE_FIXNUM(0)); - - end_critical_section(); } static void diff --git a/src/c/stacks.d b/src/c/stacks.d index 30f562bd7..33aecabde 100644 --- a/src/c/stacks.d +++ b/src/c/stacks.d @@ -171,7 +171,8 @@ bds_unwind_n(int n) static void bds_set_size(cl_index size) { - cl_index limit = (cl_env.bds_top - cl_env.bds_org); + bds_ptr old_org = cl_env.bds_org; + cl_index limit = cl_env.bds_top - old_org; if (size <= limit) { FEerror("Cannot shrink the binding stack below ~D.", 1, ecl_make_unsigned_integer(limit)); @@ -179,11 +180,16 @@ bds_set_size(cl_index size) cl_index margin = ecl_get_option(ECL_OPT_BIND_STACK_SAFETY_AREA); bds_ptr org; org = ecl_alloc_atomic(size * sizeof(*org)); - memcpy(org, cl_env.bds_org, (limit + 1) * sizeof(*org)); + + ecl_disable_interrupts(); + memcpy(org, old_org, (limit + 1) * sizeof(*org)); cl_env.bds_top = org + limit; cl_env.bds_org = org; cl_env.bds_limit = org + (size - 2*margin); cl_env.bds_size = size; + ecl_enable_interrupts(); + + cl_dealloc(old_org); } } @@ -339,7 +345,8 @@ new_frame_id(void) static void frs_set_size(cl_index size) { - cl_index limit = (cl_env.frs_top - cl_env.frs_org); + ecl_frame_ptr old_org = cl_env.frs_top; + cl_index limit = cl_env.frs_top - old_org; if (size <= limit) { FEerror("Cannot shrink frame stack below ~D.", 1, ecl_make_unsigned_integer(limit)); @@ -348,11 +355,16 @@ frs_set_size(cl_index size) ecl_frame_ptr org; size += 2*margin; org = ecl_alloc_atomic(size * sizeof(*org)); - memcpy(org, cl_env.frs_org, (limit + 1) * sizeof(*org)); + + ecl_disable_interrupts(); + memcpy(org, old_org, (limit + 1) * sizeof(*org)); cl_env.frs_top = org + limit; cl_env.frs_org = org; cl_env.frs_limit = org + (size - 2*margin); cl_env.frs_size = size; + ecl_enable_interrupts(); + + cl_dealloc(old_org); } }