static Val   allocate_heap_ram_for_pickle   (Task*  task,  Vunt  bytesize) {
    //       ============================
    //
    // Allocate a bytevector to hold the pickled datastructure.

//  Heap* heap   =  task->heap;
    int	  size_in_words =  BYTES_TO_WORDS( bytesize );
    Val	  tagword   =  MAKE_TAGWORD( size_in_words, FOUR_BYTE_ALIGNED_NONPOINTER_DATA_BTAG );

    // We probably should allocate space in the hugechunk region for these chunks.	XXX BUGGO FIXME
    //
    if (bytesize >= agegroup0_buffer_size_in_bytes(task)-(8*ONE_K_BINARY))   die ("Pickling %d bytes not supported -- increase agegroup0 buffer size.", bytesize);	// XXX BUGGO FIXME

    set_slot_in_nascent_heapchunk( task, 0, tagword );

    return   commit_nascent_heapchunk( task, size_in_words );
}
static Status   read_image  (Task* task,  Inbuf* bp,  Val* chunk_ref) {
    //          ==========
    //
    Pickle_Header	pickle_header;
    Val*		externs;

    Sib_Header*	sib_headers[ TOTAL_SIBS ];
    Sib_Header*	sib_headers_buffer;

    int sib_headers_size;

    Agegroup*  age1 =   task->heap->agegroup[ 0 ];

    if (heapio__read_block( bp, &pickle_header, sizeof(pickle_header) ) == FALSE
    ||  pickle_header.smallchunk_sibs_count > MAX_PLAIN_SIBS				// MAX_PLAIN_SIBS		def in    src/c/h/sibid.h
    ||  pickle_header.hugechunk_sibs_count  > MAX_HUGE_SIBS				// MAX_HUGE_SIBS		def in    src/c/h/sibid.h
    ){
	return FALSE;									// XXX BUGGO FIXME we gotta do better than this.
    }

    // Read the externals table:
    //
    externs = heapio__read_externs_table( bp );



    // Read the sib headers:
    //
    sib_headers_size =  (pickle_header.smallchunk_sibs_count + pickle_header.hugechunk_sibs_count)
		        *
                        sizeof( Sib_Header );
    //
    sib_headers_buffer =  (Sib_Header*) MALLOC (sib_headers_size);
    //
    if (heapio__read_block( bp, sib_headers_buffer, sib_headers_size ) == FALSE) {
	//
	FREE( sib_headers_buffer );
	return FALSE;
    }
    //
    for (int ilk = 0;  ilk < TOTAL_SIBS;  ilk++) {
        //
	sib_headers[ ilk ] =  NULL;
    }
    //
    for (int sib = 0;  sib < pickle_header.smallchunk_sibs_count;  sib++) {
        //
	Sib_Header* p =  &sib_headers_buffer[ sib ];
	//
	sib_headers[ p->chunk_ilk ] =  p;
    }



    // DO BIG CHUNK HEADERS TOO

    // Check the heap to see if there is
    // enough free space in agegroup 1:
    //
    {   Punt	agegroup0_buffer_bytesize =   agegroup0_buffer_size_in_bytes( task );
        //
	Bool needs_cleaning  =   FALSE;

	for (int ilk = 0;  ilk < MAX_PLAIN_SIBS;  ilk++) {
	    //
	    Sib* sib = age1->sib[ ilk ];

	    if (sib_headers[ilk] != NULL
		&&
               (!sib_is_active(sib)								// sib_is_active		def in    src/c/h/heap.h
	       || sib_freespace_in_bytes(sib) < sib_headers[ ilk ]->info.o.bytesize		// sib_freespace_in_bytes	def in    src/c/h/heap.h
                                               +
                                               agegroup0_buffer_bytesize
               )
            ){
		needs_cleaning = TRUE;
		sib->requested_extra_free_bytes = sib_headers[ ilk ]->info.o.bytesize;
	    }
	}

	if (needs_cleaning) {
	    //
	    if (bp->nbytes <= 0) {
		//
		call_heapcleaner( task, 1 );							// call_heapcleaner		def in   /src/c/heapcleaner/call-heapcleaner.c

	    } else {
		//
	        // The cleaning may move the buffer, so:
                
		Val buffer =  PTR_CAST( Val,  bp->base );

		{   Roots extra_roots = { &buffer, NULL };
		    //
		    call_heapcleaner_with_extra_roots (task, 1, &extra_roots );
		}

		if (buffer != PTR_CAST( Val,  bp->base )) {
		    //
		    // The buffer moved, so adjust the buffer pointers:

		    Unt8* new_base = PTR_CAST( Unt8*, buffer );

		    bp->buf  = new_base + (bp->buf - bp->base);
		    bp->base = new_base;
		}
            }
	}
    }