@@ -418,18 +418,34 @@ static LispPTR arrayblockmerger(LispPTR base, LispPTR nbase) {
418418/* */
419419/************************************************************************/
420420
421+ /*
422+ * merges this block into the block behind it, unless there are
423+ * disqualifying conditions:
424+ * merging is turned off or
425+ * this is the first block in array space or
426+ * this is the first block in the 2nd array space or
427+ * the block behind it is in use
428+ * in which case it is linked onto the freelist (fwd and backward pointers)
429+ * and added to the free block chain by size.
430+ * If it can be merged,
431+ */
421432LispPTR mergebackward (LispPTR base ) {
422433 LispPTR pbase ;
423- struct arrayblock * ptrailer ;
434+ struct arrayblock * ptrailer_np ;
424435
425436 if (base == NIL )
426437 return (NIL );
427- ptrailer = (struct arrayblock * )NativeAligned4FromLAddr (base - ARRAYBLOCKTRAILERWORDS );
438+ /* back up to get the trailer of the previous block */
439+ ptrailer_np = (struct arrayblock * )NativeAligned4FromLAddr (base - ARRAYBLOCKTRAILERWORDS );
440+ /* check that there are no disqualifying conditions for merging with previous block */
428441 if ((* ArrayMerging_word == NIL ) ||
429- ((base == * ArraySpace_word ) || ((base == * ArraySpace2_word ) || (ptrailer -> inuse == T ))))
442+ ((base == * ArraySpace_word ) || ((base == * ArraySpace2_word ) || (ptrailer_np -> inuse == T ))))
430443 return (linkblock (base ));
431- pbase = base - DLWORDSPER_CELL * ptrailer -> arlen ;
444+ /* back up to the header of the previous block */
445+ pbase = base - DLWORDSPER_CELL * ptrailer_np -> arlen ;
446+ /* check that it is free, but skip free list checks */
432447 checkarrayblock (pbase , T , NIL );
448+ /* remove it from the free list */
433449 deleteblock (pbase );
434450 return (arrayblockmerger (pbase , base ));
435451}
0 commit comments