xsbBool glstack_realloc(CTXTdeclc size_t new_size, int arity) { CPtr new_heap_bot=NULL ; /* bottom of new Global Stack area */ CPtr new_ls_bot ; /* bottom of new Local Stack area */ size_t heap_offset ; /* offsets between the old and new */ size_t local_offset ; /* stack bottoms, measured in Cells */ CPtr *cell_ptr ; Cell cell_val ; size_t i, rnum_in_trieinstr_unif_stk = (trieinstr_unif_stkptr-trieinstr_unif_stk)+1; size_t new_size_in_bytes, new_size_in_cells ; /* what a mess ! */ double expandtime ; if (new_size <= glstack.size) { // asked to shrink // new_size is space needed + half of init_size, rounded to K new_size = (((glstack.high - (byte *)top_of_localstk) + ((byte *)hreg - glstack.low)) + glstack.init_size*K/2 + (K-1)) / K; // but not smaller than init_size if (new_size < glstack.init_size) new_size = glstack.init_size; if (new_size >= glstack.size) return 0; // computed new_size won't shrink // printf("shrinking glstack from %dK to %dK\n",glstack.size,new_size); } // fprintf(stddbg,"Reallocating the Heap and Local Stack data area"); #ifdef DEBUG_VERBOSE if (LOG_REALLOC <= cur_log_level) { if (glstack.size == glstack.init_size) { xsb_dbgmsg((LOG_REALLOC,"\tBottom:\t\t%p\t\tInitial Size: %" Intfmt "K", glstack.low, glstack.size)); xsb_dbgmsg((LOG_REALLOC,"\tTop:\t\t%p", glstack.high)); } } #endif expandtime = cpu_time(); new_size_in_bytes = new_size*K ; new_size_in_cells = new_size_in_bytes/sizeof(Cell) ; /* and let's hope K stays divisible by sizeof(Cell) */ stack_boundaries ; /* Expand the data area and push the Local Stack to the high end. */ if (new_size < glstack.size) { //shrinking // move local stack down memmove(glstack.low + new_size_in_bytes-(glstack.high-(byte *)ls_top), // to ls_top, // from glstack.high - (byte *)ls_top // size ); new_heap_bot = (CPtr)realloc(heap_bot, new_size_in_bytes); heap_offset = new_heap_bot - heap_bot ; new_ls_bot = new_heap_bot + new_size_in_cells - 1 ; local_offset = new_ls_bot - ls_bot ; } else { // expanding if (!USER_MEMORY_LIMIT_EXHAUSTED(new_size)) new_heap_bot = (CPtr)realloc(heap_bot, new_size_in_bytes); if (new_heap_bot == NULL) { if (2*glstack.size == new_size) { /* if trying to double, try backing off, may not help */ size_t increment = new_size; while (new_heap_bot == NULL && increment > 40) { increment = increment/2; new_size = glstack.size + increment; new_size_in_bytes = new_size*K ; new_size_in_cells = new_size_in_bytes/sizeof(Cell) ; if (!USER_MEMORY_LIMIT_EXHAUSTED(new_size)) new_heap_bot = (CPtr)realloc(heap_bot, new_size_in_bytes); } if (new_heap_bot == NULL) { // xsb_mesg("Not enough core to resize the Heap/Local Stack! (current: %"Intfmt"; resize %"Intfmt")", // glstack.size*K,new_size_in_bytes); return 1; /* return an error output -- will be picked up later */ } } else { xsb_mesg("Not enough core to resize the Heap and Local Stack! (%" Intfmt ")",new_size_in_bytes); return 1; /* return an error output -- will be picked up later */ } } // printf("realloced heap %d -> %d\n",glstack.size,new_size); heap_offset = new_heap_bot - heap_bot ; new_ls_bot = new_heap_bot + new_size_in_cells - 1 ; local_offset = new_ls_bot - ls_bot ; #if defined(GENERAL_TAGGING) // printf("glstack expand %p %p\n",(void *)new_heap_bot,(void *)new_ls_bot+1); extend_enc_dec_as_nec(new_heap_bot,new_ls_bot+1); #endif memmove(ls_top + local_offset, /* move to */ ls_top + heap_offset, /* move from */ (ls_bot - ls_top + 1)*sizeof(Cell) ); /* number of bytes */ } initialize_glstack(heap_top + heap_offset,ls_top+local_offset); /* TLS: below, the condition should not need to be commented out. If the heap expands, there should be no pointers from heap into the local stack, so we shouldnt need to traverse the heap. However, call subumption code actually copies the substitution factor from the CPS to heap (I dont know why, but see the comment after the call to subsumptive_call_search() in slginsts_xsb_i.h), so that substitution factor pointers may point from the heap to local stack. Therefore the pointer update causes the heap-ls pointers to be harmless at glstack expansion. */ /* Update the Heap links */ // if (heap_offset != 0) { for (cell_ptr = (CPtr *)(heap_top + heap_offset); cell_ptr-- > (CPtr *)new_heap_bot; ) { reallocate_heap_or_ls_pointer(cell_ptr) ; } // } /* Update the pointers in the Local Stack */ for (cell_ptr = (CPtr *)(ls_top + local_offset); cell_ptr <= (CPtr *)new_ls_bot; cell_ptr++) { reallocate_heap_or_ls_pointer(cell_ptr) ; } /* Update the trailed variable pointers */ for (cell_ptr = (CPtr *)top_of_trail - 1; cell_ptr > (CPtr *)tcpstack.low; cell_ptr = cell_ptr - 2) { /* first the value */ reallocate_heap_or_ls_pointer(cell_ptr); /* now the address */ cell_ptr-- ; cell_val = (Cell)*cell_ptr ; #ifdef PRE_IMAGE_TRAIL if ((size_t) cell_val & PRE_IMAGE_MARK) { /* remove tag */ cell_val = (Cell) ((Cell) cell_val & ~PRE_IMAGE_MARK); /* realloc and tag */ realloc_ref_pre_image(cell_ptr,(CPtr)cell_val) ; cell_ptr--; /* realoc pre-image */ reallocate_heap_or_ls_pointer(cell_ptr); } else #endif realloc_ref(cell_ptr,(CPtr)cell_val) ; } /* Update the CP Stack pointers */ for (cell_ptr = (CPtr *)top_of_cpstack; cell_ptr < (CPtr *)tcpstack.high; cell_ptr++) { reallocate_heap_or_ls_pointer(cell_ptr) ; } /* Update the argument registers */ while (arity) { cell_ptr = (CPtr *)(reg+arity) ; reallocate_heap_or_ls_pointer(cell_ptr) ; arity-- ; } i = 0; while (i < rnum_in_trieinstr_unif_stk) { cell_ptr = (CPtr *)(trieinstr_unif_stk+i); // printf(" reallocate trieinstr_unif_stk[%d]=%p\n",i,cell_ptr); reallocate_heap_or_ls_pointer(cell_ptr) ; i++; } /* Update the system variables */ glstack.low = (byte *)new_heap_bot ; glstack.high = (byte *)(new_ls_bot + 1) ; pspace_tot_gl = pspace_tot_gl + (new_size - glstack.size)*K; glstack.size = new_size ; hreg = (CPtr)hreg + heap_offset ; hbreg = (CPtr)hbreg + heap_offset ; hfreg = (CPtr)hfreg + heap_offset ; ereg = (CPtr)ereg + local_offset ; ebreg = (CPtr)ebreg + local_offset ; efreg = (CPtr)efreg + local_offset ; if (islist(delayreg)) delayreg = (CPtr)makelist(clref_val(delayreg) + heap_offset); expandtime = cpu_time() - expandtime; xsb_dbgmsg((LOG_REALLOC,"\tNew Bottom:\t%p\t\tNew Size: %" Intfmt "K", glstack.low, glstack.size)); xsb_dbgmsg((LOG_REALLOC,"\tNew Top:\t%p", glstack.high)); xsb_dbgmsg((LOG_REALLOC, "Heap/Local Stack data area expansion - finished in %lf secs\n", expandtime)); return 0; } /* glstack_realloc */
xsbBool glstack_realloc(int new_size, int arity) { CPtr new_heap_bot ; /* bottom of new Global Stack area */ CPtr new_ls_bot ; /* bottom of new Local Stack area */ long heap_offset ; /* offsets between the old and new */ long local_offset ; /* stack bottoms, measured in Cells */ CPtr *cell_ptr ; Cell cell_val ; size_t new_size_in_bytes, new_size_in_cells ; /* what a mess ! */ long expandtime ; if (new_size <= glstack.size) return 0; xsb_dbgmsg((LOG_REALLOC, "Reallocating the Heap and Local Stack data area")); #ifdef DEBUG_VERBOSE if (LOG_REALLOC <= cur_log_level) { if (glstack.size == glstack.init_size) { xsb_dbgmsg((LOG_REALLOC,"\tBottom:\t\t%p\t\tInitial Size: %ldK", glstack.low, glstack.size)); xsb_dbgmsg((LOG_REALLOC,"\tTop:\t\t%p", glstack.high)); } } #endif expandtime = (long)(1000*cpu_time()) ; new_size_in_bytes = new_size*K ; new_size_in_cells = new_size_in_bytes/sizeof(Cell) ; /* and let's hope K stays divisible by sizeof(Cell) */ stack_boundaries ; /* Expand the data area and push the Local Stack to the high end. */ new_heap_bot = (CPtr)realloc(heap_bot, new_size_in_bytes); if (new_heap_bot == NULL) { xsb_mesg("Not enough core to resize the Heap and Local Stack!"); return 1; /* return an error output -- will be picked up later */ } heap_offset = new_heap_bot - heap_bot ; new_ls_bot = new_heap_bot + new_size_in_cells - 1 ; local_offset = new_ls_bot - ls_bot ; memmove(ls_top + local_offset, /* move to */ ls_top + heap_offset, /* move from */ (ls_bot - ls_top + 1)*sizeof(Cell) ); /* number of bytes */ /* Update the Heap links */ for (cell_ptr = (CPtr *)(heap_top + heap_offset); cell_ptr-- > (CPtr *)new_heap_bot; ) { reallocate_heap_or_ls_pointer(cell_ptr) ; } /* Update the pointers in the Local Stack */ for (cell_ptr = (CPtr *)(ls_top + local_offset); cell_ptr <= (CPtr *)new_ls_bot; cell_ptr++) { reallocate_heap_or_ls_pointer(cell_ptr) ; } /* Update the trailed variable pointers */ for (cell_ptr = (CPtr *)top_of_trail - 1; cell_ptr > (CPtr *)tcpstack.low; cell_ptr = cell_ptr - 2) { /* first the value */ reallocate_heap_or_ls_pointer(cell_ptr); /* now the address */ cell_ptr-- ; cell_val = (Cell)*cell_ptr ; realloc_ref(cell_ptr,(CPtr)cell_val) ; } /* Update the CP Stack pointers */ for (cell_ptr = (CPtr *)top_of_cpstack; cell_ptr < (CPtr *)tcpstack.high; cell_ptr++) { reallocate_heap_or_ls_pointer(cell_ptr) ; } /* Update the argument registers */ while (arity) { cell_ptr = (CPtr *)(reg+arity) ; reallocate_heap_or_ls_pointer(cell_ptr) ; arity-- ; } /* Update the system variables */ glstack.low = (byte *)new_heap_bot ; glstack.high = (byte *)(new_ls_bot + 1) ; glstack.size = new_size ; hreg = (CPtr)hreg + heap_offset ; hbreg = (CPtr)hbreg + heap_offset ; hfreg = (CPtr)hfreg + heap_offset ; ereg = (CPtr)ereg + local_offset ; ebreg = (CPtr)ebreg + local_offset ; efreg = (CPtr)efreg + local_offset ; if (islist(delayreg)) delayreg = (CPtr)makelist(clref_val(delayreg) + heap_offset); expandtime = (long)(1000*cpu_time()) - expandtime; xsb_dbgmsg((LOG_REALLOC,"\tNew Bottom:\t%p\t\tNew Size: %ldK", glstack.low, glstack.size)); xsb_dbgmsg((LOG_REALLOC,"\tNew Top:\t%p", glstack.high)); xsb_dbgmsg((LOG_REALLOC, "Heap/Local Stack data area expansion - finished in %ld msecs\n", expandtime)); return 0; } /* glstack_realloc */