SCM Repository
View of /sml/trunk/src/runtime/gc/export-heap.c
Parent Directory
|
Revision Log
Revision 1210 -
(download)
(as text)
(annotate)
Tue May 21 14:38:53 2002 UTC (20 years, 1 month ago) by jhr
File size: 10007 byte(s)
Tue May 21 14:38:53 2002 UTC (20 years, 1 month ago) by jhr
File size: 10007 byte(s)
Modified heap exporting so that it is quiet unless GCMessages are enabled.
/* export-heap.c * * COPYRIGHT (c) 1992 by AT&T Bell Laboratories. * * Routines to export an ML heap image. The basic layout of the heap image is: * * Header (Image header + Heap header) * External reference table * ML state info * ML Heap: * Big-object region descriptors * Generation descriptors * Heap image * * * Note that this will change once multiple VProcs are supported. */ #include "ml-osdep.h" #include "ml-base.h" #include "ml-limits.h" #include "memory.h" #include "ml-state.h" #include "ml-objects.h" #include "ml-globals.h" #include "ml-heap-image.h" #include "heap.h" #include "c-globals-tbl.h" #include "writer.h" #include "heap-io.h" #include "heap-output.h" #define isEXTERN(bibop, w) (isBOXED(w) && (ADDR_TO_PAGEID(bibop, w) == AID_UNMAPPED)) #define isEXTERNTAG(w) (isDESC(w) && (GET_TAG(w) == DTAG_extern)) /* local routines */ PVT status_t ExportImage (ml_state_t *msp, int kind, FILE *file); PVT export_table_t *ScanHeap (heap_t *heap); PVT status_t WriteHeap (writer_t *wr, heap_t *heap); PVT void RepairHeap (export_table_t *tbl, heap_t *heap); /* ExportHeapImage: */ status_t ExportHeapImage (ml_state_t *msp, FILE *file) { return ExportImage (msp, EXPORT_HEAP_IMAGE, file); } /* end of ExportHeapImage. */ /* ExportFnImage: */ status_t ExportFnImage (ml_state_t *msp, ml_val_t funct, FILE *file) { /* zero-out the saved parts of the ML state, and use the standard argument * register to hold the exported function closure. */ msp->ml_arg = funct; msp->ml_cont = ML_unit; msp->ml_closure = ML_unit; msp->ml_linkReg = ML_unit; msp->ml_exnCont = ML_unit; msp->ml_varReg = ML_unit; /* ??? */ msp->ml_calleeSave[0] = ML_unit; msp->ml_calleeSave[1] = ML_unit; msp->ml_calleeSave[2] = ML_unit; return ExportImage (msp, EXPORT_FN_IMAGE, file); } /* end of ExportFnImage */ /* ExportImage: */ PVT status_t ExportImage (ml_state_t *msp, int kind, FILE *file) { heap_t *heap = msp->ml_heap; /* gen_t *oldestGen = heap->gen[heap->numGens-1]; */ status_t status = SUCCESS; export_table_t *exportTbl; writer_t *wr; #define SAVE_REG(dst, src) { \ ml_val_t __src = (src); \ if (isEXTERN(BIBOP, __src)) \ __src = ExportCSymbol(exportTbl, __src); \ (dst) = __src; \ } if ((wr = WR_OpenFile(file)) == NIL(writer_t *)) return FAILURE; /* Shed any and all garbage. */ InvokeGC (msp, 0); /* minor collection */ InvokeGC (msp, MAX_NGENS); exportTbl = ScanHeap(heap); { ml_heap_hdr_t heapHdr; heapHdr.numVProcs = 1; heapHdr.numGens = heap->numGens; heapHdr.numArenas = NUM_ARENAS; heapHdr.numBOKinds = NUM_BIGOBJ_KINDS; heapHdr.numBORegions = heap->numBORegions; heapHdr.cacheGen = heap->cacheGen; heapHdr.allocSzB = heap->allocSzB / MAX_NUM_PROCS; SAVE_REG(heapHdr.pervStruct, *PTR_MLtoC(ml_val_t, PervStruct)); SAVE_REG(heapHdr.runTimeCompUnit, RunTimeCompUnit); #ifdef ASM_MATH SAVE_REG(heapHdr.mathVec, MathVec); #else heapHdr.mathVec = ML_unit; #endif HeapIO_WriteImageHeader(wr, kind); WR_Write(wr, &heapHdr, sizeof(heapHdr)); if (WR_Error(wr)) { WR_Free(wr); return FAILURE; } } /* export the ML state info */ { ml_vproc_image_t image; /* Save the live registers */ SAVE_REG(image.sigHandler, DEREF(MLSignalHandler)); SAVE_REG(image.stdArg, msp->ml_arg); SAVE_REG(image.stdCont, msp->ml_cont); SAVE_REG(image.stdClos, msp->ml_closure); SAVE_REG(image.pc, msp->ml_pc); SAVE_REG(image.exnCont, msp->ml_exnCont); SAVE_REG(image.varReg, msp->ml_varReg); SAVE_REG(image.calleeSave[0], msp->ml_calleeSave[0]); SAVE_REG(image.calleeSave[1], msp->ml_calleeSave[1]); SAVE_REG(image.calleeSave[2], msp->ml_calleeSave[2]); if (HeapIO_WriteExterns(wr, exportTbl) == FAILURE) { status = FAILURE; goto done; } WR_Write(wr, &image, sizeof(image)); if (WR_Error(wr)) { status = FAILURE; goto done; } } /* Write out the heap image */ if (WriteHeap(wr, heap) == FAILURE) status = FAILURE; done:; if (kind != EXPORT_FN_IMAGE) RepairHeap (exportTbl, heap); WR_Free(wr); return status; } /* end of ExportImage. */ /* ScanHeap: * * Scan the heap looking for exported symbols and return an export table. */ PVT export_table_t *ScanHeap (heap_t *heap) { export_table_t *tbl = NewExportTbl(); bibop_t bibop = BIBOP; int i; /* Scan the record, pair and array regions for references to external symbols */ for (i = 0; i < heap->numGens; i++) { #define PatchArena(indx) { \ arena_t *__ap = heap->gen[i]->arena[(indx)]; \ ml_val_t *__p, *__q; \ bool_t needsRepair = FALSE; \ __p = __ap->tospBase; \ __q = __ap->nextw; \ while (__p < __q) { \ ml_val_t __w = *__p; \ if (isEXTERN(bibop, __w)) { \ *__p = ExportCSymbol(tbl, __w); \ needsRepair = TRUE; \ } \ __p++; \ } \ __ap->needsRepair = needsRepair; \ } /* PatchArena */ PatchArena(RECORD_INDX); PatchArena(PAIR_INDX); PatchArena(ARRAY_INDX); } return tbl; } /* end of ScanHeap */ /* WriteHeap: * */ PVT status_t WriteHeap (writer_t *wr, heap_t *heap) { heap_arena_hdr_t *p, *arenaHdrs; bigobj_desc_t *bdp; int arenaHdrsSize, pagesize; long offset; int i, j; pagesize = GETPAGESIZE(); /* write the big-object region descriptors */ { int sz; bo_region_info_t *hdr; bigobj_region_t *rp; #ifdef BO_DEBUG SayDebug("%d bigobject regions\n", heap->numBORegions); #endif sz = heap->numBORegions * sizeof(bo_region_info_t); hdr = (bo_region_info_t *) MALLOC (sz); for (rp = heap->bigRegions, i = 0; rp != NIL(bigobj_region_t *); rp = rp->next, i++) { #ifdef BO_DEBUG PrintRegionMap(rp); #endif hdr[i].baseAddr = MEMOBJ_BASE(rp->memObj); hdr[i].firstPage = rp->firstPage; hdr[i].sizeB = MEMOBJ_SZB(rp->memObj); } WR_Write(wr, hdr, sz); if (WR_Error(wr)) { FREE (hdr); return FAILURE; } FREE(hdr); } /* initialize the arena headers. */ arenaHdrsSize = heap->numGens * (NUM_OBJ_KINDS * sizeof(heap_arena_hdr_t)); arenaHdrs = (heap_arena_hdr_t *) MALLOC (arenaHdrsSize); offset = WR_Tell(wr) + arenaHdrsSize; offset = ROUNDUP(offset, pagesize); for (p = arenaHdrs, i = 0; i < heap->numGens; i++) { for (j = 0; j < NUM_ARENAS; j++, p++) { arena_t *ap = heap->gen[i]->arena[j]; p->gen = i; p->objKind = j; p->info.o.baseAddr = (Addr_t)(ap->tospBase); p->info.o.sizeB = (Addr_t)(ap->nextw) - p->info.o.baseAddr; p->info.o.roundedSzB = ROUNDUP(p->info.o.sizeB, pagesize); p->offset = (Unsigned32_t)offset; offset += p->info.o.roundedSzB; } for (j = 0; j < NUM_BIGOBJ_KINDS; j++, p++) { int nObjs, nBOPages; bdp = heap->gen[i]->bigObjs[j]; for (nObjs = nBOPages = 0; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) { nObjs++; nBOPages += (BO_ROUNDED_SZB(bdp) >> BIGOBJ_PAGE_SHIFT); } p->gen = i; p->objKind = j; p->info.bo.numBigObjs = nObjs; p->info.bo.numBOPages = nBOPages; p->offset = (Unsigned32_t)offset; offset += ((nObjs * sizeof(bigobj_hdr_t)) + (nBOPages << BIGOBJ_PAGE_SHIFT)); } } /* write the arena headers out */ WR_Write(wr, arenaHdrs, arenaHdrsSize); if (WR_Error(wr)) { FREE (arenaHdrs); return FAILURE; } /* write out the arenas */ for (p = arenaHdrs, i = 0; i < heap->numGens; i++) { for (j = 0; j < NUM_ARENAS; j++) { if (GCMessages) { SayDebug("write %d,%d: %d bytes [%#x..%#x) @ %#x\n", i+1, j, p->info.o.sizeB, p->info.o.baseAddr, p->info.o.baseAddr+p->info.o.sizeB, p->offset); } if (p->info.o.sizeB > 0) { WR_Seek(wr, p->offset); WR_Write(wr, (void *)(p->info.o.baseAddr), p->info.o.sizeB); if (WR_Error(wr)) { FREE (arenaHdrs); return FAILURE; } } p++; } for (j = 0; j < NUM_BIGOBJ_KINDS; j++) { int hdrSizeB; bigobj_hdr_t *hdr, *q; if (p->info.bo.numBigObjs > 0) { hdrSizeB = p->info.bo.numBigObjs * sizeof(bigobj_hdr_t); hdr = (bigobj_hdr_t *) MALLOC (hdrSizeB); if (GCMessages) { SayDebug("write %d,%d: %d big objects (%d pages) @ %#x\n", i+1, j, p->info.bo.numBigObjs, p->info.bo.numBOPages, p->offset); } /* initialize the big-object headers */ q = hdr; for (bdp = heap->gen[i]->bigObjs[j]; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) { q->gen = bdp->gen; q->objKind = j; q->baseAddr = (Addr_t)(bdp->obj); q->sizeB = bdp->sizeB; q++; } /* write the big-object headers */ WR_Write (wr, hdr, hdrSizeB); if (WR_Error(wr)) { FREE (hdr); FREE (arenaHdrs); return FAILURE; } /* write the big-objects */ for (bdp = heap->gen[i]->bigObjs[j]; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) { WR_Write(wr, (char *)(bdp->obj), BO_ROUNDED_SZB(bdp)); if (WR_Error(wr)) { FREE (hdr); FREE (arenaHdrs); return FAILURE; } } FREE (hdr); } p++; } } FREE (arenaHdrs); return SUCCESS; } /* end of WriteHeap. */ /* RepairHeap: */ PVT void RepairHeap (export_table_t *tbl, heap_t *heap) { int i; /* repair the in-memory heap */ for (i = 0; i < heap->numGens; i++) { #define RepairArena(indx) { \ arena_t *__ap = heap->gen[i]->arena[(indx)]; \ if (__ap->needsRepair) { \ ml_val_t *__p, *__q; \ __p = __ap->tospBase; \ __q = __ap->nextw; \ while (__p < __q) { \ ml_val_t __w = *__p; \ if (isEXTERNTAG(__w)) { \ *__p = AddrOfCSymbol(tbl, __w); \ } \ __p++; \ } \ } \ __ap->needsRepair = FALSE; \ } /* RepairArena */ RepairArena(RECORD_INDX); RepairArena(PAIR_INDX); RepairArena(ARRAY_INDX); } FreeExportTbl (tbl); } /* end of RepairHeap */
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |