void caml_realloc_stack(asize_t required_space) { asize_t size; value * new_low, * new_high, * new_sp; value * p; size = caml_stack_high - caml_stack_low; do { if (size >= caml_max_stack_size) caml_raise_stack_overflow(); size *= 2; } while (size < caml_stack_high - caml_extern_sp + required_space); new_low = (value *) caml_stat_alloc(size * sizeof(value)); new_high = new_low + size; #define shift(ptr) \ ((char *) new_high - ((char *) caml_stack_high - (char *) (ptr))) new_sp = (value *) shift(caml_extern_sp); memmove((char *) new_sp, (char *) caml_extern_sp, (caml_stack_high - caml_extern_sp) * sizeof(value)); caml_stat_free(caml_stack_low); caml_trapsp = (value *) shift(caml_trapsp); caml_trap_barrier = (value *) shift(caml_trap_barrier); for (p = caml_trapsp; p < new_high; p = Trap_link(p)) Trap_link(p) = (value *) shift(Trap_link(p)); caml_stack_low = new_low; caml_stack_high = new_high; caml_stack_threshold = caml_stack_low + Stack_threshold / sizeof (value); caml_extern_sp = new_sp; #undef shift }
void realloc_stack() { size_t size; value * new_low, * new_high, * new_sp; value * p; assert(extern_sp >= stack_low); size = stack_high - stack_low; if (size >= Max_stack_size) raise_out_of_memory(); size *= 2; gc_message ("Growing stack to %ld kB.\n", (long) size * sizeof(value) / 1024); new_low = (value *) stat_alloc(size * sizeof(value)); new_high = new_low + size; #define shift(ptr) \ ((char *) new_high - ((char *) stack_high - (char *) (ptr))) new_sp = (value *) shift(extern_sp); memmove((char *)new_sp, (char *)extern_sp, (stack_high - extern_sp) * sizeof(value)); stat_free((char *) stack_low); trapsp = (value *) shift(trapsp); for (p = trapsp; p < new_high; p = Trap_link(p)) Trap_link(p) = (value *) shift(Trap_link(p)); stack_low = new_low; stack_high = new_high; stack_threshold = stack_low + Stack_threshold / sizeof (value); extern_sp = new_sp; #undef shift }
value reset_trapsp(value val_ek) { value * const tp = caml_stack_high - Long_val(val_ek); value *p; /* print_gl_stack("reset_trapsp"); fprintf(stderr, "to %p\n",tp); print_exc_trace("reset_trapsp: before"); */ /* We check the invariants */ myassert(caml_extern_sp >= caml_stack_low); myassert(caml_extern_sp <= caml_stack_high); myassert(caml_trapsp < caml_stack_high); myassert(tp >= caml_trapsp); myassert(caml_extern_sp < tp); /* Check the invariant that tp must occur somewhere in the Trap_link chain */ for(p=caml_trapsp; p == tp; p = Trap_link(p)) if( !(p < caml_stack_high) ) { print_gl_stack("ERROR: tp is not found in the Trap_link chain!!!"); print_exc_trace("ERROR: tp is not found..."); myassert(0); } caml_trapsp = tp; /* Reset the chain */ return Val_unit; }
/* Walk the trapsp link */ static void print_exc_trace(char * title) { value * p; fprintf(stderr, "\nexc_trace: %s\n",title); fprintf(stderr, "caml_trapsp %p\n", caml_trapsp); for(p = caml_trapsp; p < caml_stack_high; p = Trap_link(p)) fprintf(stderr, " %p\n",p); }
void caml_realloc_stack(asize_t required_space) { asize_t size; value * new_low, * new_high, * new_sp; value * p; Assert(caml_extern_sp >= caml_stack_low); size = caml_stack_high - caml_stack_low; do { if (size >= caml_max_stack_size) caml_raise_stack_overflow(); size *= 2; } while (size < caml_stack_high - caml_extern_sp + required_space); caml_gc_message (0x08, "Growing stack to %" ARCH_INTNAT_PRINTF_FORMAT "uk bytes\n", (uintnat) size * sizeof(value) / 1024); new_low = (value *) caml_stat_alloc(size * sizeof(value)); new_high = new_low + size; #define shift(ptr) \ ((char *) new_high - ((char *) caml_stack_high - (char *) (ptr))) new_sp = (value *) shift(caml_extern_sp); memmove((char *) new_sp, (char *) caml_extern_sp, (caml_stack_high - caml_extern_sp) * sizeof(value)); caml_stat_free(caml_stack_low); caml_trapsp = (value *) shift(caml_trapsp); caml_trap_barrier = (value *) shift(caml_trap_barrier); for (p = caml_trapsp; p < new_high; p = Trap_link(p)) Trap_link(p) = (value *) shift(Trap_link(p)); caml_stack_low = new_low; caml_stack_high = new_high; caml_stack_threshold = caml_stack_low + Stack_threshold / sizeof (value); caml_extern_sp = new_sp; #undef shift }
code_t caml_next_frame_pointer(value* stack_high, value ** sp, intnat * trap_spoff) { while (*sp < stack_high) { value* p = (*sp)++; if(&Trap_pc(stack_high + *trap_spoff) == p) { *trap_spoff = Trap_link(stack_high + *trap_spoff); continue; } if (Is_long(*p) && find_debug_info(Pc_val(*p)) != NULL) return Pc_val(*p); } return NULL; }
code_t caml_next_frame_pointer(value ** sp, intnat * trap_spoff) { code_t end_code = (code_t) ((char *) caml_start_code + caml_code_size); while (*sp < caml_stack_high) { value *p = (*sp)++; if(&Trap_pc(caml_stack_high + *trap_spoff) == p) { *trap_spoff = Trap_link(caml_stack_high + *trap_spoff); continue; } if (Is_long(*p) && Pc_val(*p) >= caml_start_code && Pc_val(*p) < end_code && find_debug_info((code_t)*p)) { return Pc_val(*p); } } return NULL; }
value pop_stack_fragment(value vek1, value vek2) { const ptrdiff_t ek1 = Long_val(vek1); const ptrdiff_t ek2 = Long_val(vek2); value * const tp1 = caml_stack_high - ek1; value * const tp2 = caml_stack_high - ek2; value *p, *q; mlsize_t size, i; value block; myassert(tp2 < tp1); /* stack grows downwards */ size = tp1 - tp2; /* tp2 is more recent ptr */ /* print_gl_stack("pop_stack_fragment"); fprintf(stderr, "between %p and %p (size %ld)\n",tp2,tp1,size); print_exc_trace("pop_stack_fragment: before"); */ if (size < Max_young_wosize) { block = alloc(size, 0); memcpy(&Field(block, 0), tp2, size * sizeof(value)); } else { block = alloc_shr(size, 0); for (i = 0; i < size; i++) initialize(&Field(block, i), tp2[i]); } /* We check the invariants after the allocation of block, which may cause a GC run. Stack should not be moved though. */ myassert(caml_extern_sp >= caml_stack_low); myassert(caml_extern_sp <= caml_stack_high); myassert(caml_trapsp < caml_stack_high); myassert(tp1 < caml_stack_high); myassert(caml_trapsp == tp2); myassert(caml_extern_sp < tp2); /* Check the invariant that tp1 must occur somewhere in the Trap_link chain */ for(p=caml_trapsp; p == tp1; p = Trap_link(p)) if( !(p < caml_stack_high) ) { print_gl_stack("ERROR: tp1 is not found in the Trap_link chain!!!"); print_exc_trace("ERROR: tp1 is not found..."); myassert(0); } /* Adjust the links in the copied code: make them relative to tp2: the bottom of the copied stack */ p = tp2; while (1) { myassert( p < caml_stack_high ); q = Trap_link(p); if (q == tp1) { /* end of the chain */ Field(block, (value*)(&(Trap_link(p))) - tp2) = Val_long(0); break; } Field(block, (value*)(&(Trap_link(p))) - tp2) = Val_long(q - tp2); p = q; } caml_trapsp = tp1; /* Reset the chain */ return block; }