SCM Repository
Annotation of /sml/trunk/src/runtime/gc/import-heap.c
Parent Directory
|
Revision Log
Revision 488 - (view) (download) (as text)
1 : | monnier | 2 | /* import-heap.c |
2 : | * | ||
3 : | * COPYRIGHT (c) 1992 by AT&T Bell Laboratories. | ||
4 : | * | ||
5 : | * Routines to import an ML heap image. | ||
6 : | */ | ||
7 : | |||
8 : | #include <stdio.h> | ||
9 : | #include <string.h> | ||
10 : | #include "ml-base.h" | ||
11 : | #include "machine-id.h" | ||
12 : | #include "memory.h" | ||
13 : | #include "cache-flush.h" | ||
14 : | #include "ml-state.h" | ||
15 : | #include "ml-values.h" | ||
16 : | #include "ml-objects.h" | ||
17 : | #include "ml-globals.h" | ||
18 : | #include "card-map.h" | ||
19 : | #include "heap.h" | ||
20 : | #include "ml-heap-image.h" | ||
21 : | #include "c-globals-tbl.h" | ||
22 : | #include "addr-hash.h" | ||
23 : | #include "heap-input.h" | ||
24 : | #include "heap-io.h" | ||
25 : | |||
26 : | #ifndef SEEK_SET | ||
27 : | # define SEEK_SET 0 | ||
28 : | # define SEEK_END 2 | ||
29 : | #endif | ||
30 : | |||
31 : | #ifdef DEBUG | ||
32 : | PVT void PrintRegionMap (bo_region_reloc_t *r) | ||
33 : | { | ||
34 : | bo_reloc_t *dp, *dq; | ||
35 : | int i; | ||
36 : | |||
37 : | SayDebug ("region @%#x: |", r->firstPage); | ||
38 : | for (i = 0, dq = r->objMap[0]; i < r->nPages; i++) { | ||
39 : | dp = r->objMap[i]; | ||
40 : | if (dp != dq) { | ||
41 : | SayDebug ("|"); | ||
42 : | dq = dp; | ||
43 : | } | ||
44 : | if (dp == NIL(bo_reloc_t *)) | ||
45 : | SayDebug ("_"); | ||
46 : | else | ||
47 : | SayDebug ("X"); | ||
48 : | } | ||
49 : | SayDebug ("|\n"); | ||
50 : | |||
51 : | } /* end of PrintRegionMap */ | ||
52 : | #endif | ||
53 : | |||
54 : | |||
55 : | /* local routines */ | ||
56 : | PVT void ReadHeap (inbuf_t *bp, ml_heap_hdr_t *hdr, ml_state_t *msp, ml_val_t *externs); | ||
57 : | PVT bigobj_desc_t *AllocBODesc (bigobj_desc_t *, bigobj_hdr_t *, bo_region_reloc_t *); | ||
58 : | PVT void RepairHeap ( | ||
59 : | heap_t *, aid_t *, Addr_t [MAX_NUM_GENS][NUM_ARENAS], | ||
60 : | addr_tbl_t *, ml_val_t *); | ||
61 : | PVT ml_val_t RepairWord ( | ||
62 : | ml_val_t w, aid_t *oldBIBOP, Addr_t addrOffset[MAX_NUM_GENS][NUM_ARENAS], | ||
63 : | addr_tbl_t *boRegionTbl, ml_val_t *externs); | ||
64 : | PVT int RepairBORef (aid_t *bibop, aid_t id, ml_val_t *ref, ml_val_t oldObj); | ||
65 : | PVT bo_reloc_t *AddrToRelocInfo (aid_t *, addr_tbl_t *, aid_t, Addr_t); | ||
66 : | |||
67 : | #define READ(bp,obj) HeapIO_ReadBlock(bp, &(obj), sizeof(obj)) | ||
68 : | |||
69 : | #ifdef HACKED_STANDALONE | ||
70 : | PVT long heapStart = -1; | ||
71 : | #endif | ||
72 : | |||
73 : | |||
74 : | /* ImportHeapImage: | ||
75 : | */ | ||
76 : | ml_state_t *ImportHeapImage (const char *fname, heap_params_t *params) | ||
77 : | { | ||
78 : | int i; | ||
79 : | ml_state_t *msp; | ||
80 : | ml_image_hdr_t imHdr; | ||
81 : | ml_heap_hdr_t heapHdr; | ||
82 : | ml_val_t *externs; | ||
83 : | ml_vproc_image_t image; | ||
84 : | inbuf_t inBuf; | ||
85 : | |||
86 : | /* Resolve the name of the image. If the file exists use it, otherwise try the | ||
87 : | * pathname with the machine ID as an extension. | ||
88 : | */ | ||
89 : | if ((inBuf.file = fopen(fname, "rb")) != NULL) { | ||
90 : | if (! SilentLoad) | ||
91 : | Say("loading %s ", fname); | ||
92 : | } | ||
93 : | else { | ||
94 : | char buf[1024]; | ||
95 : | |||
96 : | if (QualifyImageName(strcpy(buf, fname)) | ||
97 : | && ((inBuf.file = fopen(buf, "rb")) != NULL)) { | ||
98 : | if (! SilentLoad) | ||
99 : | Say("loading %s ", buf); | ||
100 : | } | ||
101 : | else | ||
102 : | Die ("unable to open heap image \"%s\"\n", fname); | ||
103 : | } | ||
104 : | |||
105 : | |||
106 : | inBuf.needsSwap = FALSE; | ||
107 : | inBuf.buf = NIL(Byte_t *); | ||
108 : | inBuf.nbytes = 0; | ||
109 : | |||
110 : | #ifdef HACKED_STANDALONE | ||
111 : | /* note that the seek may (will) succeed even if there's nothing there */ | ||
112 : | /* for now, we'll be content to just fail on the reads below */ | ||
113 : | if (StandAlone) { | ||
114 : | if ((fseek (inBuf.file, -sizeof(long), SEEK_END) != 0) | ||
115 : | || (fread(&heapStart, sizeof(long), 1, inBuf.file) != 1) | ||
116 : | || (fseek (inBuf.file, heapStart, SEEK_SET) != 0)) { | ||
117 : | Die ("unable to seek to internal image in stand-alone at %x\n", | ||
118 : | heapStart); | ||
119 : | } | ||
120 : | } | ||
121 : | #endif | ||
122 : | |||
123 : | READ(&inBuf, imHdr); | ||
124 : | if (imHdr.byteOrder != ORDER) | ||
125 : | Die ("incorrect byte order in heap image\n"); | ||
126 : | if (imHdr.magic != IMAGE_MAGIC) | ||
127 : | Die ("bad magic number (%#x) in heap image\n", imHdr.magic); | ||
128 : | if ((imHdr.kind != EXPORT_HEAP_IMAGE) && (imHdr.kind != EXPORT_FN_IMAGE)) | ||
129 : | Die ("bad image kind (%d) in heap image\n", imHdr.kind); | ||
130 : | READ(&inBuf, heapHdr); | ||
131 : | |||
132 : | /* check for command-line overrides of heap parameters. */ | ||
133 : | if (params->allocSz == 0) params->allocSz = heapHdr.allocSzB; | ||
134 : | if (params->numGens < heapHdr.numGens) params->numGens = heapHdr.numGens; | ||
135 : | if (params->cacheGen < 0) params->cacheGen = heapHdr.cacheGen; | ||
136 : | |||
137 : | msp = AllocMLState (FALSE, params); | ||
138 : | |||
139 : | /* get the run-time pointers into the heap */ | ||
140 : | *PTR_MLtoC(ml_val_t, PervStruct) = heapHdr.pervStruct; | ||
141 : | RunTimeCompUnit = heapHdr.runTimeCompUnit; | ||
142 : | #ifdef ASM_MATH | ||
143 : | MathVec = heapHdr.mathVec; | ||
144 : | #endif | ||
145 : | |||
146 : | /* read the externals table */ | ||
147 : | externs = HeapIO_ReadExterns (&inBuf); | ||
148 : | |||
149 : | /* read and initialize the ML state info */ | ||
150 : | READ(&inBuf, image); | ||
151 : | if (imHdr.kind == EXPORT_HEAP_IMAGE) { | ||
152 : | /* Load the live registers */ | ||
153 : | ASSIGN(MLSignalHandler, image.sigHandler); | ||
154 : | msp->ml_arg = image.stdArg; | ||
155 : | monnier | 251 | msp->ml_cont = image.stdCont; |
156 : | monnier | 2 | msp->ml_closure = image.stdClos; |
157 : | monnier | 251 | msp->ml_pc = image.pc; |
158 : | monnier | 2 | msp->ml_exnCont = image.exnCont; |
159 : | monnier | 251 | msp->ml_varReg = image.varReg; |
160 : | msp->ml_calleeSave[0] = image.calleeSave[0]; | ||
161 : | msp->ml_calleeSave[1] = image.calleeSave[1]; | ||
162 : | msp->ml_calleeSave[2] = image.calleeSave[2]; | ||
163 : | monnier | 2 | /* read the ML heap */ |
164 : | ReadHeap (&inBuf, &heapHdr, msp, externs); | ||
165 : | monnier | 8 | /* GC message are on by default for interactive images */ |
166 : | monnier | 488 | /* GCMessages = TRUE; */ |
167 : | monnier | 2 | } |
168 : | else { /* EXPORT_FN_IMAGE */ | ||
169 : | ml_val_t funct, cmdName, args; | ||
170 : | /* restore the signal handler */ | ||
171 : | ASSIGN(MLSignalHandler, image.sigHandler); | ||
172 : | /* read the ML heap */ | ||
173 : | msp->ml_arg = image.stdArg; | ||
174 : | ReadHeap (&inBuf, &heapHdr, msp, externs); | ||
175 : | /* initialize the calling context (taken from ApplyMLFn) */ | ||
176 : | funct = msp->ml_arg; | ||
177 : | msp->ml_exnCont = PTR_CtoML(handle_v+1); | ||
178 : | msp->ml_varReg = ML_unit; | ||
179 : | msp->ml_cont = PTR_CtoML(return_c); | ||
180 : | msp->ml_closure = funct; | ||
181 : | msp->ml_pc = | ||
182 : | msp->ml_linkReg = GET_CODE_ADDR(funct); | ||
183 : | /* setup the arguments to the imported function */ | ||
184 : | cmdName = ML_CString(msp, MLCmdName); | ||
185 : | args = ML_CStringList (msp, CmdLineArgs); | ||
186 : | REC_ALLOC2(msp, msp->ml_arg, cmdName, args); | ||
187 : | /* | ||
188 : | SayDebug("arg = %#x : [%#x, %#x]\n", msp->ml_arg, REC_SEL(msp->ml_arg, 0), REC_SEL(msp->ml_arg, 1)); | ||
189 : | */ | ||
190 : | monnier | 8 | /* GC message are off by default for exportFn images */ |
191 : | GCMessages = FALSE; | ||
192 : | monnier | 2 | } |
193 : | |||
194 : | FREE (externs); | ||
195 : | fclose (inBuf.file); | ||
196 : | |||
197 : | if (! SilentLoad) | ||
198 : | Say(" done\n"); | ||
199 : | |||
200 : | return msp; | ||
201 : | |||
202 : | } /* end of ImportHeapImage */ | ||
203 : | |||
204 : | /* ReadHeap: | ||
205 : | */ | ||
206 : | PVT void ReadHeap (inbuf_t *bp, ml_heap_hdr_t *hdr, ml_state_t *msp, ml_val_t *externs) | ||
207 : | { | ||
208 : | heap_t *heap = msp->ml_heap; | ||
209 : | heap_arena_hdr_t *arenaHdrs, *p, *q; | ||
210 : | int arenaHdrsSize; | ||
211 : | int i, j, k; | ||
212 : | long prevSzB[NUM_ARENAS], sz; | ||
213 : | bibop_t oldBIBOP; | ||
214 : | Addr_t addrOffset[MAX_NUM_GENS][NUM_ARENAS]; | ||
215 : | bo_region_reloc_t *boRelocInfo; | ||
216 : | addr_tbl_t *boRegionTbl; | ||
217 : | |||
218 : | /* Allocate a BIBOP for the imported heap image's address space. */ | ||
219 : | #ifdef TWO_LEVEL_MAP | ||
220 : | # error two level map not supported | ||
221 : | #else | ||
222 : | oldBIBOP = NEW_VEC (aid_t, BIBOP_SZ); | ||
223 : | #endif | ||
224 : | |||
225 : | /* read in the big-object region descriptors for the old address space */ | ||
226 : | { | ||
227 : | int sz; | ||
228 : | bo_region_info_t *boRgnHdr; | ||
229 : | bigobj_region_t *rp; | ||
230 : | |||
231 : | boRegionTbl = MakeAddrTbl(BIBOP_SHIFT+1, hdr->numBORegions); | ||
232 : | sz = hdr->numBORegions * sizeof(bo_region_info_t); | ||
233 : | boRgnHdr = (bo_region_info_t *) MALLOC (sz); | ||
234 : | HeapIO_ReadBlock (bp, boRgnHdr, sz); | ||
235 : | |||
236 : | boRelocInfo = NEW_VEC(bo_region_reloc_t, hdr->numBORegions); | ||
237 : | for (i = 0; i < hdr->numBORegions; i++) { | ||
238 : | MarkRegion(oldBIBOP, | ||
239 : | (ml_val_t *)(boRgnHdr[i].baseAddr), | ||
240 : | RND_MEMOBJ_SZB(boRgnHdr[i].sizeB), | ||
241 : | AID_BIGOBJ(1)); | ||
242 : | oldBIBOP[BIBOP_ADDR_TO_INDEX(boRgnHdr[i].baseAddr)] = AID_BIGOBJ_HDR(MAX_NUM_GENS); | ||
243 : | boRelocInfo[i].firstPage = boRgnHdr[i].firstPage; | ||
244 : | boRelocInfo[i].nPages = | ||
245 : | (boRgnHdr[i].sizeB - (boRgnHdr[i].firstPage - boRgnHdr[i].baseAddr)) | ||
246 : | >> BIGOBJ_PAGE_SHIFT; | ||
247 : | boRelocInfo[i].objMap = NEW_VEC(bo_reloc_t *, boRelocInfo[i].nPages); | ||
248 : | for (j = 0; j < boRelocInfo[i].nPages; j++) | ||
249 : | boRelocInfo[i].objMap[j] = NIL(bo_reloc_t *); | ||
250 : | AddrTblInsert (boRegionTbl, boRgnHdr[i].baseAddr, &(boRelocInfo[i])); | ||
251 : | } | ||
252 : | FREE (boRgnHdr); | ||
253 : | } | ||
254 : | |||
255 : | /* read the arena headers. */ | ||
256 : | arenaHdrsSize = hdr->numGens * NUM_OBJ_KINDS * sizeof(heap_arena_hdr_t); | ||
257 : | arenaHdrs = (heap_arena_hdr_t *) MALLOC (arenaHdrsSize); | ||
258 : | HeapIO_ReadBlock (bp, arenaHdrs, arenaHdrsSize); | ||
259 : | |||
260 : | for (i = 0; i < NUM_ARENAS; i++) | ||
261 : | prevSzB[i] = heap->allocSzB; | ||
262 : | |||
263 : | /* allocate the arenas and read in the heap image. */ | ||
264 : | for (p = arenaHdrs, i = 0; i < hdr->numGens; i++) { | ||
265 : | gen_t *gen = heap->gen[i]; | ||
266 : | |||
267 : | /* compute the space required for this generation, and mark the oldBIBOP | ||
268 : | * to reflect the old address space. | ||
269 : | */ | ||
270 : | for (q = p, j = 0; j < NUM_ARENAS; j++) { | ||
271 : | MarkRegion (oldBIBOP, | ||
272 : | (ml_val_t *)(q->info.o.baseAddr), | ||
273 : | RND_MEMOBJ_SZB(q->info.o.sizeB), | ||
274 : | gen->arena[j]->id); | ||
275 : | sz = q->info.o.sizeB + prevSzB[j]; | ||
276 : | if ((j == PAIR_INDX) && (sz > 0)) | ||
277 : | sz += 2*WORD_SZB; | ||
278 : | gen->arena[j]->tospSizeB = RND_MEMOBJ_SZB(sz); | ||
279 : | prevSzB[j] = q->info.o.sizeB; | ||
280 : | q++; | ||
281 : | } | ||
282 : | |||
283 : | /* Allocate space for the generation */ | ||
284 : | if (NewGeneration(gen) == FAILURE) | ||
285 : | Die ("unable to allocated space for generation %d\n", i+1); | ||
286 : | if (isACTIVE(gen->arena[ARRAY_INDX])) | ||
287 : | NewDirtyVector (gen); | ||
288 : | |||
289 : | /* read in the arenas for this generation and initialize the | ||
290 : | * address offset table. | ||
291 : | */ | ||
292 : | for (j = 0; j < NUM_ARENAS; j++) { | ||
293 : | arena_t *ap = gen->arena[j]; | ||
294 : | long offset; | ||
295 : | |||
296 : | if (p->info.o.sizeB > 0) { | ||
297 : | addrOffset[i][j] = (Addr_t)(ap->tospBase) - (Addr_t)(p->info.o.baseAddr); | ||
298 : | #ifdef HACKED_STANDALONE | ||
299 : | /* assuming here that ReadHeap is only called from ImportHeapImage | ||
300 : | * and that ImportHeapImage is only called from LoadML on startup. | ||
301 : | * Otherwise, StandAlone needs to be set to FALSE after the intial | ||
302 : | * load; or need extra offset param here, etc. | ||
303 : | */ | ||
304 : | offset = (long)(p->offset) + (StandAlone ? heapStart : 0); | ||
305 : | #else | ||
306 : | offset = (long)(p->offset); | ||
307 : | #endif | ||
308 : | if (fseek (bp->file, offset, SEEK_SET) != 0) | ||
309 : | Die("unable to seek on heap image\n"); | ||
310 : | HeapIO_ReadBlock(bp, (ap->tospBase), p->info.o.sizeB); | ||
311 : | ap->nextw = (ml_val_t *)((Addr_t)(ap->tospBase) + p->info.o.sizeB); | ||
312 : | ap->oldTop = ap->tospBase; | ||
313 : | } | ||
314 : | else if (isACTIVE(ap)) { | ||
315 : | ap->oldTop = ap->tospBase; | ||
316 : | } | ||
317 : | if (! SilentLoad) { | ||
318 : | Say("."); | ||
319 : | } | ||
320 : | p++; | ||
321 : | } | ||
322 : | /* read in the big-object arenas */ | ||
323 : | for (j = 0; j < NUM_BIGOBJ_KINDS; j++) { | ||
324 : | Addr_t totSizeB; | ||
325 : | bigobj_desc_t *freeObj, *bdp; | ||
326 : | bigobj_region_t *freeRegion; | ||
327 : | bigobj_hdr_t *boHdrs; | ||
328 : | int boHdrSizeB, indx; | ||
329 : | bo_region_reloc_t *region; | ||
330 : | |||
331 : | if (p->info.bo.numBOPages > 0) { | ||
332 : | totSizeB = p->info.bo.numBOPages << BIGOBJ_PAGE_SHIFT; | ||
333 : | freeObj = BO_AllocRegion (heap, totSizeB); | ||
334 : | freeRegion = freeObj->region; | ||
335 : | freeRegion->minGen = i; | ||
336 : | MarkRegion (BIBOP, (ml_val_t *)freeRegion, | ||
337 : | MEMOBJ_SZB(freeRegion->memObj), AID_BIGOBJ(i)); | ||
338 : | BIBOP[BIBOP_ADDR_TO_INDEX(freeRegion)] = AID_BIGOBJ_HDR(i); | ||
339 : | |||
340 : | /* read in the big-object headers */ | ||
341 : | boHdrSizeB = p->info.bo.numBigObjs * sizeof(bigobj_hdr_t); | ||
342 : | boHdrs = (bigobj_hdr_t *) MALLOC (boHdrSizeB); | ||
343 : | HeapIO_ReadBlock (bp, boHdrs, boHdrSizeB); | ||
344 : | |||
345 : | /* read in the big-objects */ | ||
346 : | HeapIO_ReadBlock (bp, (void *)(freeObj->obj), totSizeB); | ||
347 : | if (j == CODE_INDX) { | ||
348 : | FlushICache ((void *)(freeObj->obj), totSizeB); | ||
349 : | } | ||
350 : | |||
351 : | /* setup the big-object descriptors and per-object relocation info */ | ||
352 : | for (k = 0; k < p->info.bo.numBigObjs; k++) { | ||
353 : | /* find the region relocation info for the object's region in | ||
354 : | * the exported heap. | ||
355 : | */ | ||
356 : | for (indx = BIBOP_ADDR_TO_INDEX(boHdrs[k].baseAddr); | ||
357 : | !BO_IS_HDR(oldBIBOP[indx]); | ||
358 : | indx--) | ||
359 : | continue; | ||
360 : | region = LookupBORegion (boRegionTbl, indx); | ||
361 : | /* allocate the big-object descriptor for the object, and | ||
362 : | * link it into the list of big-objects for its generation. | ||
363 : | */ | ||
364 : | bdp = AllocBODesc (freeObj, &(boHdrs[k]), region); | ||
365 : | bdp->next = gen->bigObjs[j]; | ||
366 : | gen->bigObjs[j] = bdp; | ||
367 : | ASSERT(bdp->gen == i+1); | ||
368 : | |||
369 : | if (DumpObjectStrings && (j == CODE_INDX)) { | ||
370 : | /* dump the comment string of the code object */ | ||
371 : | char buf[256]; | ||
372 : | monnier | 8 | if (BO_GetCodeObjTag(bdp, buf, sizeof(buf)) != NIL(char *)) |
373 : | SayDebug ("[%6d bytes] %s\n", bdp->sizeB, buf); | ||
374 : | monnier | 2 | } |
375 : | } | ||
376 : | |||
377 : | if (freeObj != bdp) { | ||
378 : | /* there was some extra space left in the region */ | ||
379 : | ADD_BODESC(heap->freeBigObjs, freeObj); | ||
380 : | } | ||
381 : | |||
382 : | FREE (boHdrs); | ||
383 : | } | ||
384 : | if (! SilentLoad) { | ||
385 : | Say("."); | ||
386 : | } | ||
387 : | p++; | ||
388 : | } | ||
389 : | } | ||
390 : | |||
391 : | RepairHeap (heap, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
392 : | |||
393 : | /* Adjust the run-time globals that point into the heap */ | ||
394 : | *PTR_MLtoC(ml_val_t, PervStruct) = RepairWord ( | ||
395 : | *PTR_MLtoC(ml_val_t, PervStruct), | ||
396 : | oldBIBOP, addrOffset, boRegionTbl, externs); | ||
397 : | RunTimeCompUnit = RepairWord ( | ||
398 : | RunTimeCompUnit, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
399 : | #ifdef ASM_MATH | ||
400 : | MathVec = RepairWord (MathVec, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
401 : | #endif | ||
402 : | |||
403 : | /* Adjust the ML registers to the new address space */ | ||
404 : | ASSIGN(MLSignalHandler, RepairWord ( | ||
405 : | DEREF(MLSignalHandler), oldBIBOP, addrOffset, boRegionTbl, externs)); | ||
406 : | monnier | 251 | msp->ml_arg = RepairWord ( |
407 : | msp->ml_arg, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
408 : | msp->ml_cont = RepairWord ( | ||
409 : | msp->ml_cont, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
410 : | msp->ml_closure = RepairWord ( | ||
411 : | msp->ml_closure, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
412 : | msp->ml_pc = RepairWord ( | ||
413 : | msp->ml_pc, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
414 : | msp->ml_linkReg = RepairWord ( | ||
415 : | msp->ml_linkReg, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
416 : | msp->ml_exnCont = RepairWord ( | ||
417 : | msp->ml_exnCont, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
418 : | msp->ml_varReg = RepairWord ( | ||
419 : | msp->ml_varReg, oldBIBOP, addrOffset, boRegionTbl, externs); | ||
420 : | msp->ml_calleeSave[0] = RepairWord ( | ||
421 : | msp->ml_calleeSave[0], oldBIBOP, addrOffset, boRegionTbl, externs); | ||
422 : | msp->ml_calleeSave[1] = RepairWord ( | ||
423 : | msp->ml_calleeSave[1], oldBIBOP, addrOffset, boRegionTbl, externs); | ||
424 : | msp->ml_calleeSave[2] = RepairWord ( | ||
425 : | msp->ml_calleeSave[2], oldBIBOP, addrOffset, boRegionTbl, externs); | ||
426 : | monnier | 2 | |
427 : | /* release storage */ | ||
428 : | for (i = 0; i < hdr->numBORegions; i++) { | ||
429 : | bo_reloc_t *p; | ||
430 : | for (p = NIL(bo_reloc_t *), j = 0; j < boRelocInfo[i].nPages; j++) { | ||
431 : | if ((boRelocInfo[i].objMap[j] != NIL(bo_reloc_t *)) | ||
432 : | && (boRelocInfo[i].objMap[j] != p)) { | ||
433 : | FREE (boRelocInfo[i].objMap[j]); | ||
434 : | p = boRelocInfo[i].objMap[j]; | ||
435 : | } | ||
436 : | } | ||
437 : | } | ||
438 : | FreeAddrTbl (boRegionTbl, FALSE); | ||
439 : | FREE (boRelocInfo); | ||
440 : | FREE (arenaHdrs); | ||
441 : | FREE (oldBIBOP); | ||
442 : | |||
443 : | /* reset the sweep_nextw pointers */ | ||
444 : | for (i = 0; i < heap->numGens; i++) { | ||
445 : | gen_t *gen = heap->gen[i]; | ||
446 : | for (j = 0; j < NUM_ARENAS; j++) { | ||
447 : | arena_t *ap = gen->arena[j]; | ||
448 : | if (isACTIVE(ap)) | ||
449 : | ap->sweep_nextw = ap->nextw; | ||
450 : | } | ||
451 : | } | ||
452 : | |||
453 : | } /* end of ReadHeap. */ | ||
454 : | |||
455 : | /* AllocBODesc: | ||
456 : | * | ||
457 : | */ | ||
458 : | PVT bigobj_desc_t *AllocBODesc ( | ||
459 : | bigobj_desc_t *free, | ||
460 : | bigobj_hdr_t *objHdr, | ||
461 : | bo_region_reloc_t *oldRegion) | ||
462 : | { | ||
463 : | bigobj_region_t *region; | ||
464 : | bigobj_desc_t *newObj; | ||
465 : | bo_reloc_t *relocInfo; | ||
466 : | int i, totSzB, firstPage, npages; | ||
467 : | |||
468 : | totSzB = ROUNDUP(objHdr->sizeB, BIGOBJ_PAGE_SZB); | ||
469 : | npages = (totSzB >> BIGOBJ_PAGE_SHIFT); | ||
470 : | region = free->region; | ||
471 : | if (free->sizeB == totSzB) | ||
472 : | /* allocate the whole free area to the object */ | ||
473 : | newObj = free; | ||
474 : | else { | ||
475 : | /* split the free object */ | ||
476 : | newObj = NEW_OBJ(bigobj_desc_t); | ||
477 : | newObj->obj = free->obj; | ||
478 : | newObj->region = region; | ||
479 : | free->obj = (Addr_t)(free->obj) + totSzB; | ||
480 : | free->sizeB -= totSzB; | ||
481 : | firstPage = ADDR_TO_BOPAGE(region, newObj->obj); | ||
482 : | for (i = 0; i < npages; i++) | ||
483 : | region->objMap[firstPage+i] = newObj; | ||
484 : | } | ||
485 : | |||
486 : | newObj->sizeB = objHdr->sizeB; | ||
487 : | newObj->state = BO_YOUNG; | ||
488 : | newObj->gen = objHdr->gen; | ||
489 : | newObj->objc = objHdr->objKind; | ||
490 : | region->nFree -= npages; | ||
491 : | |||
492 : | /* setup the relocation info */ | ||
493 : | relocInfo = NEW_OBJ(bo_reloc_t); | ||
494 : | relocInfo->oldAddr = objHdr->baseAddr; | ||
495 : | relocInfo->newObj = newObj; | ||
496 : | firstPage = ADDR_TO_BOPAGE(oldRegion, objHdr->baseAddr); | ||
497 : | for (i = 0; i < npages; i++) | ||
498 : | oldRegion->objMap[firstPage+i] = relocInfo; | ||
499 : | |||
500 : | return newObj; | ||
501 : | |||
502 : | } /* end of AllocBODesc */ | ||
503 : | |||
504 : | /* RepairHeap: | ||
505 : | * | ||
506 : | * Scan the heap, replacing external references with their addresses and | ||
507 : | * adjusting pointers. | ||
508 : | */ | ||
509 : | PVT void RepairHeap ( | ||
510 : | heap_t *heap, | ||
511 : | aid_t *oldBIBOP, | ||
512 : | Addr_t addrOffset[MAX_NUM_GENS][NUM_ARENAS], | ||
513 : | addr_tbl_t *boRegionTbl, | ||
514 : | ml_val_t *externs) | ||
515 : | { | ||
516 : | int i; | ||
517 : | |||
518 : | for (i = 0; i < heap->numGens; i++) { | ||
519 : | gen_t *gen = heap->gen[i]; | ||
520 : | #ifndef BIT_CARDS | ||
521 : | #define MARK(cm, p, g) MARK_CARD(cm, p, g) | ||
522 : | #else | ||
523 : | #define MARK(cm, p, g) MARK_CARD(cm, p) | ||
524 : | #endif | ||
525 : | #define RepairArena(indx) { \ | ||
526 : | arena_t *__ap = gen->arena[(indx)]; \ | ||
527 : | ml_val_t *__p, *__q; \ | ||
528 : | __p = __ap->tospBase; \ | ||
529 : | __q = __ap->nextw; \ | ||
530 : | while (__p < __q) { \ | ||
531 : | ml_val_t __w = *__p; \ | ||
532 : | int __gg, __objc; \ | ||
533 : | if (isBOXED(__w)) { \ | ||
534 : | Addr_t __obj = PTR_MLtoADDR(__w); \ | ||
535 : | aid_t __aid = ADDR_TO_PAGEID(oldBIBOP, __obj); \ | ||
536 : | if (IS_BIGOBJ_AID(__aid)) { \ | ||
537 : | bo_reloc_t *__dp; \ | ||
538 : | __dp = AddrToRelocInfo (oldBIBOP, boRegionTbl, \ | ||
539 : | __aid, __obj); \ | ||
540 : | *__p = PTR_CtoML((__obj - __dp->oldAddr) \ | ||
541 : | + __dp->newObj->obj); \ | ||
542 : | monnier | 8 | __gg = __dp->newObj->gen-1; \ |
543 : | monnier | 2 | } \ |
544 : | else { \ | ||
545 : | __gg = EXTRACT_GEN(__aid)-1; \ | ||
546 : | __objc = EXTRACT_OBJC(__aid)-1; \ | ||
547 : | *__p = PTR_CtoML(__obj + addrOffset[__gg][__objc]); \ | ||
548 : | } \ | ||
549 : | if (((indx) == ARRAY_INDX) && (__gg < i)) { \ | ||
550 : | MARK(gen->dirty, __p, __gg+1); /** **/ \ | ||
551 : | } \ | ||
552 : | } \ | ||
553 : | else if (isEXTERNTAG(__w)) { \ | ||
554 : | *__p = externs[EXTERNID(__w)]; \ | ||
555 : | } \ | ||
556 : | __p++; \ | ||
557 : | } \ | ||
558 : | } /* RepairArena */ | ||
559 : | |||
560 : | RepairArena(RECORD_INDX); | ||
561 : | RepairArena(PAIR_INDX); | ||
562 : | RepairArena(ARRAY_INDX); | ||
563 : | } | ||
564 : | |||
565 : | } /* end of RepairHeap */ | ||
566 : | |||
567 : | /* RepairWord: | ||
568 : | */ | ||
569 : | PVT ml_val_t RepairWord ( | ||
570 : | ml_val_t w, | ||
571 : | aid_t *oldBIBOP, | ||
572 : | Addr_t addrOffset[MAX_NUM_GENS][NUM_ARENAS], | ||
573 : | addr_tbl_t *boRegionTbl, | ||
574 : | ml_val_t *externs) | ||
575 : | { | ||
576 : | if (isBOXED(w)) { | ||
577 : | Addr_t obj = PTR_MLtoADDR(w); | ||
578 : | aid_t aid = ADDR_TO_PAGEID(oldBIBOP, obj); | ||
579 : | if (IS_BIGOBJ_AID(aid)) { | ||
580 : | bo_reloc_t *dp; | ||
581 : | dp = AddrToRelocInfo (oldBIBOP, boRegionTbl, aid, obj); | ||
582 : | return PTR_CtoML((obj - dp->oldAddr) + dp->newObj->obj); | ||
583 : | } | ||
584 : | else { | ||
585 : | int g = EXTRACT_GEN(aid)-1; | ||
586 : | int objc = EXTRACT_OBJC(aid)-1; | ||
587 : | return PTR_CtoML(PTR_MLtoC(char, w) + addrOffset[g][objc]); | ||
588 : | } | ||
589 : | } | ||
590 : | else if (isEXTERNTAG(w)) { | ||
591 : | return externs[EXTERNID(w)]; | ||
592 : | } | ||
593 : | else | ||
594 : | return w; | ||
595 : | |||
596 : | } /* end of RepairWord */ | ||
597 : | |||
598 : | |||
599 : | /* AddrToRelocInfo: | ||
600 : | */ | ||
601 : | PVT bo_reloc_t *AddrToRelocInfo ( | ||
602 : | aid_t *oldBIBOP, | ||
603 : | addr_tbl_t *boRegionTbl, | ||
604 : | aid_t id, | ||
605 : | Addr_t oldObj) | ||
606 : | { | ||
607 : | int indx; | ||
608 : | bo_region_reloc_t *region; | ||
609 : | |||
610 : | for (indx = BIBOP_ADDR_TO_INDEX(oldObj); !BO_IS_HDR(id); id = oldBIBOP[--indx]) | ||
611 : | continue; | ||
612 : | |||
613 : | /* find the old region descriptor */ | ||
614 : | region = LookupBORegion (boRegionTbl, indx); | ||
615 : | |||
616 : | if (region == NIL(bo_region_reloc_t *)) | ||
617 : | Die ("unable to map big-object @ %#x; index = %#x, id = %#x\n", | ||
618 : | oldObj, indx, (unsigned)id); | ||
619 : | |||
620 : | return ADDR_TO_BODESC(region, oldObj); | ||
621 : | |||
622 : | } /* end of AddrToRelocInfo */ |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |