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; } } } }