void heap_sort(buf *buf, int low, int high) { repair_heap(buf, low, high); for (int i = high; i > low; i--) { swap(buf, i, low); sift_down(buf, low, i-1, low); } }
static void read_heap ( // ========= // Inbuf* bp, Heap_Header* header, Task* task, Val* externs ){ Heap* heap = task->heap; Sib_Header* sib_headers; Sib_Header* p; Sib_Header* q; int sib_headers_bytesize; int i, j, k; long prevSzB[MAX_PLAIN_SIBS], size; Sibid* oldBOOK2SIBID; Punt addrOffset[MAX_AGEGROUPS][MAX_PLAIN_SIBS]; Hugechunk_Quire_Relocation_Info* boRelocInfo; Addresstable* boRegionTable; // Allocate a book_to_sibid__global for the imported // heap image's address space: // #ifdef TWO_LEVEL_MAP #error two level map not supported #else oldBOOK2SIBID = MALLOC_VEC (Sibid, BOOK2SIBID_TABLE_SIZE_IN_SLOTS); #endif // Read in the hugechunk region descriptors // for the old address space: // { int size; Hugechunk_Quire_Header* boRgnHdr; boRegionTable = make_address_hashtable(LOG2_BOOK_BYTESIZE+1, header->hugechunk_quire_count); size = header->hugechunk_quire_count * sizeof(Hugechunk_Quire_Header); boRgnHdr = (Hugechunk_Quire_Header*) MALLOC (size); heapio__read_block( bp, boRgnHdr, size ); boRelocInfo = MALLOC_VEC(Hugechunk_Quire_Relocation_Info, header->hugechunk_quire_count); for (i = 0; i < header->hugechunk_quire_count; i++) { set_book2sibid_entries_for_range(oldBOOK2SIBID, (Val*)(boRgnHdr[i].base_address), BOOKROUNDED_BYTESIZE(boRgnHdr[i].bytesize), HUGECHUNK_DATA_SIBID(1) ); oldBOOK2SIBID[GET_BOOK_CONTAINING_POINTEE(boRgnHdr[i].base_address)] = HUGECHUNK_RECORD_SIBID(MAX_AGEGROUPS); boRelocInfo[i].first_ram_quantum = boRgnHdr[i].first_ram_quantum; boRelocInfo[i].page_count = (boRgnHdr[i].bytesize - (boRgnHdr[i].first_ram_quantum - boRgnHdr[i].base_address)) >> LOG2_HUGECHUNK_RAM_QUANTUM_IN_BYTES; boRelocInfo[i].hugechunk_page_to_hugechunk = MALLOC_VEC(Hugechunk_Relocation_Info*, boRelocInfo[i].page_count); for (j = 0; j < boRelocInfo[i].page_count; j++) { // boRelocInfo[i].hugechunk_page_to_hugechunk[j] = NULL; } addresstable_insert (boRegionTable, boRgnHdr[i].base_address, &(boRelocInfo[i])); } FREE (boRgnHdr); } // Read the sib headers: // sib_headers_bytesize = header->active_agegroups * TOTAL_SIBS * sizeof( Sib_Header ); // sib_headers = (Sib_Header*) MALLOC( sib_headers_bytesize ); // heapio__read_block( bp, sib_headers, sib_headers_bytesize ); for (i = 0; i < MAX_PLAIN_SIBS; i++) { // prevSzB[i] = task->heap_allocation_buffer_bytesize; } // Allocate the sib buffers and read in the heap image: // for (p = sib_headers, i = 0; i < header->active_agegroups; i++) { // Agegroup* age = heap->agegroup[ i ]; // Compute the space required for this agegroup, // and mark the oldBOOK2SIBID to reflect the old address space: // for (q = p, j = 0; j < MAX_PLAIN_SIBS; j++) { set_book2sibid_entries_for_range ( // oldBOOK2SIBID, (Val*) q->info.o.base_address, BOOKROUNDED_BYTESIZE( q->info.o.bytesize ), age->sib[ j ]->id ); size = q->info.o.bytesize + prevSzB[j]; if (j == RO_CONSCELL_SIB && size > 0 ){ size += 2*WORD_BYTESIZE; } age->sib[ j ]->tospace.bytesize = BOOKROUNDED_BYTESIZE( size ); prevSzB[ j ] = q->info.o.bytesize; q++; } if (set_up_tospace_sib_buffers_for_agegroup(age) == FALSE) { die ("unable to allocated space for agegroup %d\n", i+1); } if (sib_is_active( age->sib[ RW_POINTERS_SIB ] )) { // sib_is_active def in src/c/h/heap.h // make_new_coarse_inter_agegroup_pointers_map_for_agegroup (age); } // Read in the sib buffers for this agegroup // and initialize the address offset table: // for (int j = 0; j < MAX_PLAIN_SIBS; j++) { // Sib* ap = age->sib[ j ]; if (p->info.o.bytesize > 0) { addrOffset[i][j] = (Punt)(ap->tospace.start) - (Punt)(p->info.o.base_address); heapio__seek( bp, (long) p->offset ); heapio__read_block( bp, (ap->tospace.start), p->info.o.bytesize ); ap->tospace.used_end = (Val *)((Punt)(ap->tospace.start) + p->info.o.bytesize); ap->fromspace.seniorchunks_end = ap->tospace.start; } else if (sib_is_active(ap)) { ap->fromspace.seniorchunks_end = ap->tospace.start; } if (verbosity__global > 0) say("."); p++; } // Read in the hugechunk sib buffers (currently just codechunks): // for (int ilk = 0; ilk < MAX_HUGE_SIBS; ilk++) { // MAX_HUGE_SIBS def in src/c/h/sibid.h // Punt totSizeB; Hugechunk* free_chunk; Hugechunk* bdp = NULL; // Without this initialization, gcc -Wall gives a 'possible uninitialized use' warning. Hugechunk_Quire* free_quire; Hugechunk_Header* boHdrs; int boHdrSizeB; int index; Hugechunk_Quire_Relocation_Info* region; if (p->info.bo.hugechunk_quanta_count > 0) { // totSizeB = p->info.bo.hugechunk_quanta_count << LOG2_HUGECHUNK_RAM_QUANTUM_IN_BYTES; free_chunk = allocate_hugechunk_quire( heap, totSizeB ); free_quire = free_chunk->hugechunk_quire; free_quire->age_of_youngest_live_chunk_in_quire = i; set_book2sibid_entries_for_range ( // book_to_sibid__global, (Val*) free_quire, BYTESIZE_OF_QUIRE( free_quire->quire ), HUGECHUNK_DATA_SIBID( i ) ); book_to_sibid__global[ GET_BOOK_CONTAINING_POINTEE( free_quire ) ] = HUGECHUNK_RECORD_SIBID( i ); // Read in the hugechunk headers: // boHdrSizeB = p->info.bo.hugechunk_count * sizeof(Hugechunk_Header); // boHdrs = (Hugechunk_Header*) MALLOC (boHdrSizeB); // heapio__read_block (bp, boHdrs, boHdrSizeB); // Read in the hugechunks: // heapio__read_block( bp, (void *)(free_chunk->chunk), totSizeB ); // if (ilk == CODE__HUGE_SIB) { // ilk = 0 == CODE__HUGE_SIB def in src/c/h/sibid.h // flush_instruction_cache ((void *)(free_chunk->chunk), totSizeB); } // Set up the hugechunk descriptors // and per-chunk relocation info: // for (k = 0; k < p->info.bo.hugechunk_count; k++) { // // Find the region relocation info for the // chunk's region in the exported heap: // for (index = GET_BOOK_CONTAINING_POINTEE(boHdrs[k].base_address); !SIBID_ID_IS_BIGCHUNK_RECORD(oldBOOK2SIBID[index]); index--) continue; region = LOOK_UP_HUGECHUNK_REGION (boRegionTable, index); // Allocate the hugechunk record for // the chunk and link it into the list // of hugechunks for its agegroup. // bdp = allocate_a_hugechunk( free_chunk, &(boHdrs[k]), region ); bdp->next = age->hugechunks[ ilk ]; age->hugechunks[ ilk ] = bdp; ASSERT( bdp->gen == i+1 ); if (codechunk_comment_display_is_enabled__global && ilk == CODE__HUGE_SIB ){ // Dump the comment string of the code chunk. Unt8* namestring; // if ((namestring = get_codechunk_comment_string_else_null( bdp ))) { debug_say ("[%6d bytes] %s\n", bdp->bytesize, (char*)namestring); } } } if (free_chunk != bdp) { // if p->info.bo.hugechunk_count can be zero, 'bdp' value here may be bogus. XXX BUGGO FIXME. // // There was some extra space left in the region: // insert_hugechunk_in_doubly_linked_list( heap->hugechunk_freelist, free_chunk); // insert_hugechunk_in_doubly_linked_list def in src/c/h/heap.h } FREE (boHdrs); } if (verbosity__global > 0) say("."); p++; } } repair_heap (heap, oldBOOK2SIBID, addrOffset, boRegionTable, externs); // Adjust the run-time globals // that point into the heap: // *PTR_CAST( Val*, PERVASIVE_PACKAGE_PICKLE_LIST_REFCELL__GLOBAL ) = repair_word( *PTR_CAST( Val*, PERVASIVE_PACKAGE_PICKLE_LIST_REFCELL__GLOBAL ), oldBOOK2SIBID, addrOffset, boRegionTable, externs ); runtime_package__global = repair_word( runtime_package__global, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); #ifdef ASM_MATH mathvec__global = repair_word (mathvec__global, oldBOOK2SIBID, addrOffset, boRegionTable, externs); #endif // Adjust the Mythryl registers // to the new address space: // ASSIGN( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL, // repair_word ( // DEREF( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL ), oldBOOK2SIBID, addrOffset, boRegionTable, externs ) ); task->argument = repair_word( task->argument, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->fate = repair_word( task->fate, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->current_closure = repair_word( task->current_closure, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->program_counter = repair_word( task->program_counter, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->link_register = repair_word (task->link_register, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->exception_fate = repair_word( task->exception_fate, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->current_thread = repair_word( task->current_thread, oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->callee_saved_registers[0] = repair_word( task->callee_saved_registers[0], oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->callee_saved_registers[1] = repair_word( task->callee_saved_registers[1], oldBOOK2SIBID, addrOffset, boRegionTable, externs ); task->callee_saved_registers[2] = repair_word( task->callee_saved_registers[2], oldBOOK2SIBID, addrOffset, boRegionTable, externs ); // Release storage: // for (i = 0; i < header->hugechunk_quire_count; i++) { // Hugechunk_Relocation_Info* p; for (p = NULL, j = 0; j < boRelocInfo[i].page_count; j++) { if ((boRelocInfo[i].hugechunk_page_to_hugechunk[j] != NULL) && (boRelocInfo[i].hugechunk_page_to_hugechunk[j] != p)) { FREE (boRelocInfo[i].hugechunk_page_to_hugechunk[j]); p = boRelocInfo[i].hugechunk_page_to_hugechunk[j]; } } } free_address_table( boRegionTable, FALSE ); FREE( boRelocInfo ); FREE( sib_headers ); FREE( oldBOOK2SIBID ); // Reset the tospace.swept_end pointers: // for (int i = 0; i < heap->active_agegroups; i++) { // Agegroup* age = heap->agegroup[i]; // for (int j = 0; j < MAX_PLAIN_SIBS; j++) { // Sib* ap = age->sib[ j ]; // if (sib_is_active(ap)) { // sib_is_active def in src/c/h/heap.h // ap->tospace.swept_end = ap->tospace.used_end; } } } } // fun read_heap
static void read_heap ( inbuf_t* bp, lib7_heap_hdr_t* header, lib7_state_t* lib7_state, lib7_val_t* externs ) { heap_t* heap = lib7_state->lib7_heap; heap_arena_hdr_t *arenaHdrs, *p, *q; int arenaHdrsSize; int i, j, k; long prevSzB[NUM_ARENAS], size; bibop_t oldBIBOP; Addr_t addrOffset[MAX_NUM_GENS][NUM_ARENAS]; bo_region_reloc_t *boRelocInfo; addr_table_t *boRegionTable; /* Allocate a BIBOP for the imported * heap image's address space: */ #ifdef TWO_LEVEL_MAP # error two level map not supported #else oldBIBOP = NEW_VEC (aid_t, BIBOP_SZ); #endif /* Read in the big-chunk region descriptors * for the old address space: */ { int size; bo_region_info_t* boRgnHdr; boRegionTable = MakeAddrTable(BIBOP_SHIFT+1, header->numBORegions); size = header->numBORegions * sizeof(bo_region_info_t); boRgnHdr = (bo_region_info_t *) MALLOC (size); HeapIO_ReadBlock (bp, boRgnHdr, size); boRelocInfo = NEW_VEC(bo_region_reloc_t, header->numBORegions); for (i = 0; i < header->numBORegions; i++) { MarkRegion(oldBIBOP, (lib7_val_t *)(boRgnHdr[i].baseAddr), RND_HEAP_CHUNK_SZB(boRgnHdr[i].sizeB), AID_BIGCHUNK(1) ); oldBIBOP[BIBOP_ADDR_TO_INDEX(boRgnHdr[i].baseAddr)] = AID_BIGCHUNK_HDR(MAX_NUM_GENS); boRelocInfo[i].firstPage = boRgnHdr[i].firstPage; boRelocInfo[i].nPages = (boRgnHdr[i].sizeB - (boRgnHdr[i].firstPage - boRgnHdr[i].baseAddr)) >> BIGCHUNK_PAGE_SHIFT; boRelocInfo[i].chunkMap = NEW_VEC(bo_reloc_t *, boRelocInfo[i].nPages); for (j = 0; j < boRelocInfo[i].nPages; j++) { boRelocInfo[i].chunkMap[j] = NULL; } AddrTableInsert (boRegionTable, boRgnHdr[i].baseAddr, &(boRelocInfo[i])); } FREE (boRgnHdr); } /* Read the arena headers: */ arenaHdrsSize = header->numGens * NUM_CHUNK_KINDS * sizeof(heap_arena_hdr_t); arenaHdrs = (heap_arena_hdr_t *) MALLOC (arenaHdrsSize); HeapIO_ReadBlock (bp, arenaHdrs, arenaHdrsSize); for (i = 0; i < NUM_ARENAS; i++) { prevSzB[i] = heap->allocSzB; } /* Allocate the arenas and read in the heap image: */ for (p = arenaHdrs, i = 0; i < header->numGens; i++) { gen_t *gen = heap->gen[i]; /* Compute the space required for this generation, * and mark the oldBIBOP to reflect the old address space: */ for (q = p, j = 0; j < NUM_ARENAS; j++) { MarkRegion (oldBIBOP, (lib7_val_t *)(q->info.o.baseAddr), RND_HEAP_CHUNK_SZB(q->info.o.sizeB), gen->arena[j]->id); size = q->info.o.sizeB + prevSzB[j]; if ((j == PAIR_INDEX) && (size > 0)) size += 2*WORD_SZB; gen->arena[j]->tospSizeB = RND_HEAP_CHUNK_SZB(size); prevSzB[j] = q->info.o.sizeB; q++; } /* Allocate space for the generation: */ if (NewGeneration(gen) == FAILURE) { Die ("unable to allocated space for generation %d\n", i+1); } if (isACTIVE(gen->arena[ARRAY_INDEX])) { NewDirtyVector (gen); } /* Read in the arenas for this generation * and initialize the address offset table: */ for (j = 0; j < NUM_ARENAS; j++) { arena_t* ap = gen->arena[j]; if (p->info.o.sizeB > 0) { addrOffset[i][j] = (Addr_t)(ap->tospBase) - (Addr_t)(p->info.o.baseAddr); HeapIO_Seek (bp, (long)(p->offset)); HeapIO_ReadBlock(bp, (ap->tospBase), p->info.o.sizeB); ap->nextw = (lib7_val_t *)((Addr_t)(ap->tospBase) + p->info.o.sizeB); ap->oldTop = ap->tospBase; } else if (isACTIVE(ap)) { ap->oldTop = ap->tospBase; } if (verbosity > 0) say("."); p++; } /* Read in the big-chunk arenas: */ for (j = 0; j < NUM_BIGCHUNK_KINDS; j++) { Addr_t totSizeB; bigchunk_desc_t *freeChunk, *bdp; bigchunk_region_t *freeRegion; bigchunk_hdr_t *boHdrs; int boHdrSizeB, index; bo_region_reloc_t *region; if (p->info.bo.numBOPages > 0) { totSizeB = p->info.bo.numBOPages << BIGCHUNK_PAGE_SHIFT; freeChunk = BO_AllocRegion (heap, totSizeB); freeRegion = freeChunk->region; freeRegion->minGen = i; MarkRegion (BIBOP, (lib7_val_t *)freeRegion, HEAP_CHUNK_SZB( freeRegion->heap_chunk ), AID_BIGCHUNK(i)); BIBOP[BIBOP_ADDR_TO_INDEX(freeRegion)] = AID_BIGCHUNK_HDR(i); /* Read in the big-chunk headers */ boHdrSizeB = p->info.bo.numBigChunks * sizeof(bigchunk_hdr_t); boHdrs = (bigchunk_hdr_t *) MALLOC (boHdrSizeB); HeapIO_ReadBlock (bp, boHdrs, boHdrSizeB); /* Read in the big-chunks: */ HeapIO_ReadBlock (bp, (void *)(freeChunk->chunk), totSizeB); if (j == CODE_INDEX) { FlushICache ((void *)(freeChunk->chunk), totSizeB); } /* Set up the big-chunk descriptors * and per-chunk relocation info: */ for (k = 0; k < p->info.bo.numBigChunks; k++) { /* find the region relocation info for the chunk's region in * the exported heap. */ for (index = BIBOP_ADDR_TO_INDEX(boHdrs[k].baseAddr); !BO_IS_HDR(oldBIBOP[index]); index--) continue; region = LookupBORegion (boRegionTable, index); /* Allocate the big-chunk descriptor for * the chunk and link it into the list * of big-chunks for its generation. */ bdp = AllocBODesc (freeChunk, &(boHdrs[k]), region); bdp->next = gen->bigChunks[j]; gen->bigChunks[j] = bdp; ASSERT(bdp->gen == i+1); if (show_code_chunk_comments && (j == CODE_INDEX)) { /* Dump the comment string of the code chunk: */ char* namestring; if ((namestring = BO_GetCodeChunkTag(bdp))) { SayDebug ("[%6d bytes] %s\n", bdp->sizeB, namestring); } } } if (freeChunk != bdp) { /* There was some extra space left in the region: */ ADD_BODESC(heap->freeBigChunks, freeChunk); } FREE (boHdrs); } if (verbosity > 0) say("."); p++; } } repair_heap (heap, oldBIBOP, addrOffset, boRegionTable, externs); /* Adjust the run-time globals * that point into the heap: */ *PTR_LIB7toC(lib7_val_t, PervasiveStruct) = repair_word ( *PTR_LIB7toC(lib7_val_t, PervasiveStruct), oldBIBOP, addrOffset, boRegionTable, externs); runtimeCompileUnit = repair_word( runtimeCompileUnit, oldBIBOP, addrOffset, boRegionTable, externs ); #ifdef ASM_MATH MathVec = repair_word (MathVec, oldBIBOP, addrOffset, boRegionTable, externs); #endif /* Adjust the Lib7 registers to the new address space */ ASSIGN(Lib7SignalHandler, repair_word ( DEREF(Lib7SignalHandler), oldBIBOP, addrOffset, boRegionTable, externs) ); lib7_state->lib7_argument = repair_word ( lib7_state->lib7_argument, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_fate = repair_word ( lib7_state->lib7_fate, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_closure = repair_word ( lib7_state->lib7_closure, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_program_counter = repair_word ( lib7_state->lib7_program_counter, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_link_register = repair_word ( lib7_state->lib7_link_register, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_exception_fate = repair_word ( lib7_state->lib7_exception_fate, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_current_thread = repair_word ( lib7_state->lib7_current_thread, oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_calleeSave[0] = repair_word ( lib7_state->lib7_calleeSave[0], oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_calleeSave[1] = repair_word ( lib7_state->lib7_calleeSave[1], oldBIBOP, addrOffset, boRegionTable, externs ); lib7_state->lib7_calleeSave[2] = repair_word ( lib7_state->lib7_calleeSave[2], oldBIBOP, addrOffset, boRegionTable, externs ); /* Release storage: */ for (i = 0; i < header->numBORegions; i++) { bo_reloc_t *p; for (p = NULL, j = 0; j < boRelocInfo[i].nPages; j++) { if ((boRelocInfo[i].chunkMap[j] != NULL) && (boRelocInfo[i].chunkMap[j] != p)) { FREE (boRelocInfo[i].chunkMap[j]); p = boRelocInfo[i].chunkMap[j]; } } } FreeAddrTable (boRegionTable, FALSE); FREE (boRelocInfo); FREE (arenaHdrs); FREE (oldBIBOP); /* Reset the sweep_nextw pointers: */ for (i = 0; i < heap->numGens; i++) { gen_t *gen = heap->gen[i]; for (j = 0; j < NUM_ARENAS; j++) { arena_t *ap = gen->arena[j]; if (isACTIVE(ap)) ap->sweep_nextw = ap->nextw; } } } /* read_heap. */