+ if (excess > extra_bytes * 2 && (*real_morecore) (0) == last_heap->end)
+ {
+ /* Keep extra_bytes worth of empty space.
+ And don't free anything unless we can free at least extra_bytes. */
+ excess -= extra_bytes;
+
+ if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess)
+ {
+ /* This heap should have no blocs in it. */
+ if (last_heap->first_bloc != NIL_BLOC
+ || last_heap->last_bloc != NIL_BLOC)
+ abort ();
+
+ /* Return the last heap, with its header, to the system. */
+ excess = (char *)last_heap->end - (char *)last_heap->start;
+ last_heap = last_heap->prev;
+ last_heap->next = NIL_HEAP;
+ }
+ else
+ {
+ excess = (char *) last_heap->end
+ - (char *) ROUNDUP ((char *)last_heap->end - excess);
+ last_heap->end = (char *) last_heap->end - excess;
+ }
+
+ if ((*real_morecore) (- excess) == 0)
+ {
+ /* If the system didn't want that much memory back, adjust
+ the end of the last heap to reflect that. This can occur
+ if break_value is still within the original data segment. */
+ last_heap->end = (char *) last_heap->end + excess;
+ /* Make sure that the result of the adjustment is accurate.
+ It should be, for the else clause above; the other case,
+ which returns the entire last heap to the system, seems
+ unlikely to trigger this mode of failure. */
+ if (last_heap->end != (*real_morecore) (0))
+ abort ();
+ }
+ }
+}
+
+/* Return the total size in use by relocating allocator,
+ above where malloc gets space. */
+
+long
+r_alloc_size_in_use ()
+{
+ return (char *) break_value - (char *) virtual_break_value;
+}
+\f
+/* The meat - allocating, freeing, and relocating blocs. */