Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/export-heap.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/export-heap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (view) (download) (as text)

1 : monnier 2 /* export-heap.c
2 :     *
3 :     * COPYRIGHT (c) 1992 by AT&T Bell Laboratories.
4 :     *
5 :     * Routines to export an ML heap image. The basic layout of the heap image is:
6 :     *
7 :     * Header (Image header + Heap header)
8 :     * External reference table
9 :     * ML state info
10 :     * ML Heap:
11 :     * Big-object region descriptors
12 :     * Generation descriptors
13 :     * Heap image
14 :     *
15 :     *
16 :     * Note that this will change once multiple VProcs are supported.
17 :     */
18 :    
19 :     #include "ml-osdep.h"
20 :     #include "ml-base.h"
21 :     #include "ml-limits.h"
22 :     #include "memory.h"
23 :     #include "ml-state.h"
24 :     #include "ml-objects.h"
25 :     #include "ml-globals.h"
26 :     #include "ml-heap-image.h"
27 :     #include "heap.h"
28 :     #include "c-globals-tbl.h"
29 :     #include "writer.h"
30 :     #include "heap-io.h"
31 :    
32 :     #define isEXTERN(bibop, w) (isBOXED(w) && (ADDR_TO_PAGEID(bibop, w) == AID_UNMAPPED))
33 :     #define isEXTERNTAG(w) (isDESC(w) && (GET_TAG(w) == DTAG_extern))
34 :    
35 :     /* local routines */
36 :     PVT status_t ExportImage (ml_state_t *msp, int kind, FILE *file);
37 :     PVT export_table_t *ScanHeap (heap_t *heap);
38 :     PVT status_t WriteHeap (writer_t *wr, heap_t *heap);
39 :     PVT void RepairHeap (export_table_t *tbl, heap_t *heap);
40 :    
41 :    
42 :     /* ExportHeapImage:
43 :     */
44 :     status_t ExportHeapImage (ml_state_t *msp, FILE *file)
45 :     {
46 :     return ExportImage (msp, EXPORT_HEAP_IMAGE, file);
47 :    
48 :     } /* end of ExportHeapImage. */
49 :    
50 :    
51 :     /* ExportFnImage:
52 :     */
53 :     status_t ExportFnImage (ml_state_t *msp, ml_val_t funct, FILE *file)
54 :     {
55 :     int i;
56 :    
57 :     /* zero-out the saved parts of the ML state, and use the standard argument
58 :     * register to hold the exported function closure.
59 :     */
60 :     #if (CALLEESAVE > 0)
61 :     for (i = 0; i < CALLEESAVE; i++)
62 :     msp->ml_calleeSave(i) = ML_unit;
63 :     #endif
64 :     msp->ml_closure = ML_unit;
65 :     msp->ml_cont = ML_unit;
66 :     msp->ml_exnCont = ML_unit;
67 :     msp->ml_pc = ML_unit;
68 :     msp->ml_arg = funct;
69 :    
70 :     return ExportImage (msp, EXPORT_FN_IMAGE, file);
71 :    
72 :     } /* end of ExportFnImage */
73 :    
74 :    
75 :     /* ExportImage:
76 :     */
77 :     PVT status_t ExportImage (ml_state_t *msp, int kind, FILE *file)
78 :     {
79 :     heap_t *heap = msp->ml_heap;
80 :     gen_t *oldestGen = heap->gen[heap->numGens-1];
81 :     status_t status = SUCCESS;
82 :     int i, j;
83 :     export_table_t *exportTbl;
84 :     writer_t *wr;
85 :    
86 :     #define SAVE_REG(dst, src) { \
87 :     ml_val_t __src = (src); \
88 :     if (isEXTERN(BIBOP, __src)) \
89 :     __src = ExportCSymbol(exportTbl, __src); \
90 :     (dst) = __src; \
91 :     }
92 :    
93 :     if ((wr = WR_OpenFile(file)) == NIL(writer_t *))
94 :     return FAILURE;
95 :    
96 :     /* Shed any and all garbage. */
97 :     InvokeGC (msp, 0); /* minor collection */
98 :     InvokeGC (msp, MAX_NGENS);
99 :    
100 :     exportTbl = ScanHeap(heap);
101 :    
102 :     {
103 :     ml_heap_hdr_t heapHdr;
104 :    
105 :     heapHdr.numVProcs = 1;
106 :     heapHdr.numGens = heap->numGens;
107 :     heapHdr.numArenas = NUM_ARENAS;
108 :     heapHdr.numBOKinds = NUM_BIGOBJ_KINDS;
109 :     heapHdr.numBORegions = heap->numBORegions;
110 :     heapHdr.cacheGen = heap->cacheGen;
111 :     heapHdr.allocSzB = heap->allocSzB / MAX_NUM_PROCS;
112 :    
113 :     SAVE_REG(heapHdr.pervStruct, *PTR_MLtoC(ml_val_t, PervStruct));
114 :     SAVE_REG(heapHdr.runTimeCompUnit, RunTimeCompUnit);
115 :     #ifdef ASM_MATH
116 :     SAVE_REG(heapHdr.mathVec, MathVec);
117 :     #else
118 :     heapHdr.mathVec = ML_unit;
119 :     #endif
120 :    
121 :     HeapIO_WriteImageHeader(wr, kind);
122 :     WR_Write(wr, &heapHdr, sizeof(heapHdr));
123 :     if (WR_Error(wr)) {
124 :     WR_Free(wr);
125 :     return FAILURE;
126 :     }
127 :     }
128 :    
129 :     /* export the ML state info */
130 :     {
131 :     ml_vproc_image_t image;
132 :    
133 :     /* Save the live registers */
134 :     SAVE_REG(image.sigHandler, DEREF(MLSignalHandler));
135 :     SAVE_REG(image.stdArg, msp->ml_arg);
136 :     SAVE_REG(image.stdClos, msp->ml_closure);
137 :     SAVE_REG(image.stdCont, msp->ml_cont);
138 :     SAVE_REG(image.exnCont, msp->ml_exnCont);
139 :     SAVE_REG(image.pc, msp->ml_pc);
140 :     #if (CALLEESAVE > 0)
141 :     for (i = 0; i < CALLEESAVE; i++)
142 :     SAVE_REG(image.calleeSaves[i], msp->ml_calleeSave(i));
143 :     #endif
144 :     #if (FLOAT_CALLEESAVE > 0)
145 :     /** SAVE FLOAT CALLEE SAVES **/
146 :     #endif
147 :    
148 :     if (HeapIO_WriteExterns(wr, exportTbl) == FAILURE) {
149 :     status = FAILURE;
150 :     goto done;
151 :     }
152 :    
153 :     WR_Write(wr, &image, sizeof(image));
154 :     if (WR_Error(wr)) {
155 :     status = FAILURE;
156 :     goto done;
157 :     }
158 :     }
159 :    
160 :     /* Write out the heap image */
161 :     if (WriteHeap(wr, heap) == FAILURE)
162 :     status = FAILURE;
163 :    
164 :     done:;
165 :     if (kind != EXPORT_FN_IMAGE)
166 :     RepairHeap (exportTbl, heap);
167 :    
168 :     WR_Free(wr);
169 :    
170 :     return status;
171 :    
172 :     } /* end of ExportImage. */
173 :    
174 :    
175 :     /* ScanHeap:
176 :     *
177 :     * Scan the heap looking for exported symbols and return an export table.
178 :     */
179 :     PVT export_table_t *ScanHeap (heap_t *heap)
180 :     {
181 :     export_table_t *tbl = NewExportTbl();
182 :     bibop_t bibop = BIBOP;
183 :     int i;
184 :    
185 :     /* Scan the record, pair and array regions for references to external symbols */
186 :     for (i = 0; i < heap->numGens; i++) {
187 :     #define PatchArena(indx) { \
188 :     arena_t *__ap = heap->gen[i]->arena[(indx)]; \
189 :     ml_val_t *__p, *__q; \
190 :     bool_t needsRepair = FALSE; \
191 :     __p = __ap->tospBase; \
192 :     __q = __ap->nextw; \
193 :     while (__p < __q) { \
194 :     ml_val_t __w = *__p; \
195 :     if (isEXTERN(bibop, __w)) { \
196 :     *__p = ExportCSymbol(tbl, __w); \
197 :     needsRepair = TRUE; \
198 :     } \
199 :     __p++; \
200 :     } \
201 :     __ap->needsRepair = needsRepair; \
202 :     } /* PatchArena */
203 :    
204 :     PatchArena(RECORD_INDX);
205 :     PatchArena(PAIR_INDX);
206 :     PatchArena(ARRAY_INDX);
207 :     }
208 :    
209 :     return tbl;
210 :    
211 :     } /* end of ScanHeap */
212 :    
213 :    
214 :     /* WriteHeap:
215 :     *
216 :     */
217 :     PVT status_t WriteHeap (writer_t *wr, heap_t *heap)
218 :     {
219 :     heap_arena_hdr_t *p, *arenaHdrs;
220 :     bigobj_desc_t *bdp;
221 :     int arenaHdrsSize, pagesize;
222 :     long offset;
223 :     int i, j;
224 :    
225 :     pagesize = GETPAGESIZE();
226 :    
227 :     /* write the big-object region descriptors */
228 :     {
229 :     int sz;
230 :     bo_region_info_t *hdr;
231 :     bigobj_region_t *rp;
232 :    
233 :     #ifdef BO_DEBUG
234 :     SayDebug("%d bigobject regions\n", heap->numBORegions);
235 :     #endif
236 :     sz = heap->numBORegions * sizeof(bo_region_info_t);
237 :     hdr = (bo_region_info_t *) MALLOC (sz);
238 :     for (rp = heap->bigRegions, i = 0; rp != NIL(bigobj_region_t *); rp = rp->next, i++) {
239 :     #ifdef BO_DEBUG
240 :     PrintRegionMap(rp);
241 :     #endif
242 :     hdr[i].baseAddr = MEMOBJ_BASE(rp->memObj);
243 :     hdr[i].firstPage = rp->firstPage;
244 :     hdr[i].sizeB = MEMOBJ_SZB(rp->memObj);
245 :     }
246 :    
247 :     WR_Write(wr, hdr, sz);
248 :     if (WR_Error(wr)) {
249 :     FREE (hdr);
250 :     return FAILURE;
251 :     }
252 :    
253 :     FREE(hdr);
254 :     }
255 :    
256 :     /* initialize the arena headers. */
257 :     arenaHdrsSize = heap->numGens * (NUM_OBJ_KINDS * sizeof(heap_arena_hdr_t));
258 :     arenaHdrs = (heap_arena_hdr_t *) MALLOC (arenaHdrsSize);
259 :     offset = WR_Tell(wr) + arenaHdrsSize;
260 :     offset = ROUNDUP(offset, pagesize);
261 :     for (p = arenaHdrs, i = 0; i < heap->numGens; i++) {
262 :     for (j = 0; j < NUM_ARENAS; j++, p++) {
263 :     arena_t *ap = heap->gen[i]->arena[j];
264 :     p->gen = i;
265 :     p->objKind = j;
266 :     p->info.o.baseAddr = (Addr_t)(ap->tospBase);
267 :     p->info.o.sizeB = (Addr_t)(ap->nextw) - p->info.o.baseAddr;
268 :     p->info.o.roundedSzB = ROUNDUP(p->info.o.sizeB, pagesize);
269 :     p->offset = (Unsigned32_t)offset;
270 :     offset += p->info.o.roundedSzB;
271 :     }
272 :     for (j = 0; j < NUM_BIGOBJ_KINDS; j++, p++) {
273 :     int nObjs, nBOPages;
274 :     bdp = heap->gen[i]->bigObjs[j];
275 :     for (nObjs = nBOPages = 0; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) {
276 :     nObjs++;
277 :     nBOPages += (BO_ROUNDED_SZB(bdp) >> BIGOBJ_PAGE_SHIFT);
278 :     }
279 :     p->gen = i;
280 :     p->objKind = j;
281 :     p->info.bo.numBigObjs = nObjs;
282 :     p->info.bo.numBOPages = nBOPages;
283 :     p->offset = (Unsigned32_t)offset;
284 :     offset += ((nObjs * sizeof(bigobj_hdr_t))
285 :     + (nBOPages << BIGOBJ_PAGE_SHIFT));
286 :     }
287 :     }
288 :    
289 :     /* write the arena headers out */
290 :     WR_Write(wr, arenaHdrs, arenaHdrsSize);
291 :     if (WR_Error(wr)) {
292 :     FREE (arenaHdrs);
293 :     return FAILURE;
294 :     }
295 :    
296 :     /* write out the arenas */
297 :     for (p = arenaHdrs, i = 0; i < heap->numGens; i++) {
298 :     for (j = 0; j < NUM_ARENAS; j++) {
299 :     SayDebug("write %d,%d: %d bytes [%#x..%#x) @ %#x\n",
300 :     i+1, j, p->info.o.sizeB, p->info.o.baseAddr, p->info.o.baseAddr+p->info.o.sizeB,
301 :     p->offset);
302 :     if (p->info.o.sizeB > 0) {
303 :     WR_Seek(wr, p->offset);
304 :     WR_Write(wr, (void *)(p->info.o.baseAddr), p->info.o.sizeB);
305 :     if (WR_Error(wr)) {
306 :     FREE (arenaHdrs);
307 :     return FAILURE;
308 :     }
309 :     }
310 :     p++;
311 :     }
312 :     for (j = 0; j < NUM_BIGOBJ_KINDS; j++) {
313 :     int hdrSizeB;
314 :     bigobj_hdr_t *hdr, *q;
315 :    
316 :     if (p->info.bo.numBigObjs > 0) {
317 :     hdrSizeB = p->info.bo.numBigObjs * sizeof(bigobj_hdr_t);
318 :     hdr = (bigobj_hdr_t *) MALLOC (hdrSizeB);
319 :     SayDebug("write %d,%d: %d big objects (%d pages) @ %#x\n",
320 :     i+1, j, p->info.bo.numBigObjs, p->info.bo.numBOPages, p->offset);
321 :     /* initialize the big-object headers */
322 :     q = hdr;
323 :     for (bdp = heap->gen[i]->bigObjs[j]; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) {
324 :     q->gen = bdp->gen;
325 :     q->objKind = j;
326 :     q->baseAddr = (Addr_t)(bdp->obj);
327 :     q->sizeB = bdp->sizeB;
328 :     q++;
329 :     }
330 :     /* write the big-object headers */
331 :     WR_Write (wr, hdr, hdrSizeB);
332 :     if (WR_Error(wr)) {
333 :     FREE (hdr);
334 :     FREE (arenaHdrs);
335 :     return FAILURE;
336 :     }
337 :     /* write the big-objects */
338 :     for (bdp = heap->gen[i]->bigObjs[j]; bdp != NIL(bigobj_desc_t *); bdp = bdp->next) {
339 :     WR_Write(wr, (char *)(bdp->obj), BO_ROUNDED_SZB(bdp));
340 :     if (WR_Error(wr)) {
341 :     FREE (hdr);
342 :     FREE (arenaHdrs);
343 :     return FAILURE;
344 :     }
345 :     }
346 :     FREE (hdr);
347 :     }
348 :     p++;
349 :     }
350 :     }
351 :    
352 :     FREE (arenaHdrs);
353 :    
354 :     return SUCCESS;
355 :    
356 :     } /* end of WriteHeap. */
357 :    
358 :     /* RepairHeap:
359 :     */
360 :     PVT void RepairHeap (export_table_t *tbl, heap_t *heap)
361 :     {
362 :     int i;
363 :    
364 :     /* repair the in-memory heap */
365 :     for (i = 0; i < heap->numGens; i++) {
366 :     #define RepairArena(indx) { \
367 :     arena_t *__ap = heap->gen[i]->arena[(indx)]; \
368 :     if (__ap->needsRepair) { \
369 :     ml_val_t *__p, *__q; \
370 :     __p = __ap->tospBase; \
371 :     __q = __ap->nextw; \
372 :     while (__p < __q) { \
373 :     ml_val_t __w = *__p; \
374 :     if (isEXTERNTAG(__w)) { \
375 :     *__p = AddrOfCSymbol(tbl, __w); \
376 :     } \
377 :     __p++; \
378 :     } \
379 :     } \
380 :     __ap->needsRepair = FALSE; \
381 :     } /* RepairArena */
382 :    
383 :     RepairArena(RECORD_INDX);
384 :     RepairArena(PAIR_INDX);
385 :     RepairArena(ARRAY_INDX);
386 :     }
387 :    
388 :     FreeExportTbl (tbl);
389 :    
390 :     } /* end of RepairHeap */

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0