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

SCM Repository

[smlnj] View of /sml/trunk/src/runtime/gc/blast-out.c
ViewVC logotype

View of /sml/trunk/src/runtime/gc/blast-out.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 569 - (download) (as text) (annotate)
Tue Mar 7 04:01:07 2000 UTC (19 years, 8 months ago) by blume
File size: 8815 byte(s)
- size info in BOOTLIST
     * no fixed upper limits for number of bootfiles or length of
       bootfile names in runtime
     * falling back to old behavior if no BOOTLIST size info found
- allocation size heuristics in .run-sml
     * tries to read cache size from /proc/cpuinfo (this is important for
        small-cache Celeron systems!)
- install.sh robustified
- CM manual updates
- paranoid mode
     * no more CMB.deliver() (i.e., all done by CMB.make())
     * can re-use existing sml.boot.* files
     * init.cmi now treated as library
     * library stamps for consistency checks
- sml.boot.<arch>-<os>/PIDMAP file
     * This file is read by the CM startup code.  This is used to minimize
       the amount of dynamic state that needs to be stowed away for the
       purpose of sharing between interactive system and user code.
- CM.Anchor.anchor instead of CM.Anchor.{set,cancel}
     * Upon request by Elsa.  Anchors now controlled by get-set-pair
       like most other CM state variables.
- Compiler.CMSA eliminated
     * No longer supported by CM anyway.
- fixed bugs in pickler that kept biting Stefan
     * past refs to past refs (was caused by the possibility that
       ad-hoc sharing is more discriminating than hash-cons sharing)
     * integer overflow on LargeInt.minInt
- ml-{lex,yacc} build scripts now use new mechanism
  for building standalone programs
- fixed several gcc -Wall warnings that were caused by missing header
  files, missing initializations, etc., in runtime (not all warnings
  eliminated, though)
/* blast-out.c
 *
 * COPYRIGHT (c) 1993 by AT&T Bell Laboratories.
 */

#include "ml-osdep.h"
#include "ml-base.h"
#include "ml-values.h"
#include "ml-objects.h"
#include "ml-heap-image.h"
#include "c-globals-tbl.h"
#include "addr-hash.h"
#include "gc.h"
#include "blast-out.h"
#include "heap-output.h"
#include "heap-io.h"

#define BLAST_ERROR	ML_unit

/* local routines */
PVT ml_val_t BlastUnboxed (ml_state_t *msp, ml_val_t obj);
PVT ml_val_t BlastHeap (ml_state_t *msp, ml_val_t obj, blast_res_t *info);
PVT ml_val_t AllocBlastData (ml_state_t *msp, Addr_t sizeB);


/* BlastOut:
 *
 * Linearize an ML object into a vector of bytes; return ML_unit on errors.
 */
ml_val_t BlastOut (ml_state_t *msp, ml_val_t obj)
{
    blast_res_t		res;
    int			gen;
    ml_val_t		blastedObj;

  /* Collect allocation space */
    InvokeGCWithRoots (msp, 0, &obj, NIL(ml_val_t *));

    gen = GetObjGen (obj);

    if (gen == -1) {
      /* unboxed */
	blastedObj = BlastUnboxed (msp, obj);
    }
    else { /* a regular ML object */
      /* do the blast GC */
/* DEBUG  CheckHeap (msp->ml_heap, msp->ml_heap->numGens); */
	res = BlastGC (msp, &obj, gen);

      /* blast out the image */
	blastedObj = BlastHeap (msp, obj, &res);

      /* repair the heap or finish the GC */
	BlastGC_FinishUp (msp, &res);

/* DEBUG CheckHeap (msp->ml_heap, res.maxGen); */
    }

    return blastedObj;

} /* end of BlastOut */


/* BlastUnboxed:
 *
 * Blast out an unboxed value.
 */
PVT ml_val_t BlastUnboxed (ml_state_t *msp, ml_val_t obj)
{
    ml_blast_hdr_t  blastHdr;
    int		    szB = sizeof(ml_image_hdr_t) + sizeof(ml_blast_hdr_t);
    ml_val_t	    blastedObj;
    writer_t	    *wr;

  /* allocate space for the object */
    blastedObj = AllocBlastData (msp, szB);
    wr = WR_OpenMem (PTR_MLtoC(Byte_t, blastedObj), szB);

    HeapIO_WriteImageHeader (wr, BLAST_UNBOXED);

    blastHdr.numArenas		= 0;
    blastHdr.numBOKinds		= 0;
    blastHdr.numBORegions	= 0;
    blastHdr.hasCode		= FALSE;
    blastHdr.rootObj		= obj;

    WR_Write(wr, &blastHdr, sizeof(blastHdr));

    if (WR_Error(wr))
	return ML_unit;
    else {
	WR_Free(wr);
	SEQHDR_ALLOC (msp, blastedObj, DESC_string, blastedObj, szB);
	return blastedObj;
    }

} /* end of BlastUnboxed */


/* BlastHeap:
 *
 * Blast out the heap image.
 */
PVT ml_val_t BlastHeap (ml_state_t *msp, ml_val_t obj, blast_res_t *info)
{
    heap_t		*heap = msp->ml_heap;
    int			maxGen = info->maxGen;
    Addr_t		totArenaSzB[NUM_ARENAS], totSzB;
    struct {
	Addr_t		    base;	/* the base address of the arena in the heap */
	Addr_t		    offset;	/* the relative position in the merged */
					/* arena. */
    }			adjust[MAX_NUM_GENS][NUM_ARENAS];
    heap_arena_hdr_t	*p, *arenaHdrs[NUM_OBJ_KINDS], *arenaHdrsBuf;
    int			arenaHdrSz, i, j, numArenas;
    ml_val_t	        blastedObj;
    writer_t		*wr;

  /* compute the arena offsets in the heap image */
    for (i = 0;  i < NUM_ARENAS; i++)
	totArenaSzB[i] = 0;
  /* the embedded literals go first */
    totArenaSzB[STRING_INDX] = BlastGC_AssignLitAddrs (info, STRING_INDX, 0);
/* DEBUG SayDebug("%d bytes of string literals\n", totArenaSzB[STRING_INDX]); */
    for (i = 0;  i < maxGen;  i++) {
	for (j = 0;  j < NUM_ARENAS;  j++) {
	    arena_t	*ap = heap->gen[i]->arena[j];
	    adjust[i][j].offset = totArenaSzB[j];
	    if (isACTIVE(ap)) {
/* DEBUG SayDebug("[%d][%d] base = %#x, nextw = %#x, %d bytes\n", */
/* DEBUG i, j, ap->tospBase, ap->nextw, (Addr_t)(ap->nextw) - (Addr_t)(ap->tospBase)); */
		totArenaSzB[j] += (Addr_t)(ap->nextw) - (Addr_t)(ap->tospBase);
		adjust[i][j].base = (Addr_t)(ap->tospBase);
	    }
	    else
		adjust[i][j].base = 0;
	}
    }
/* DEBUG for (i = 0;  i < NUM_ARENAS;  i++) SayDebug ("arena %d: %d bytes\n", i+1, totArenaSzB[i]); */
    /** WHAT ABOUT THE BIG OBJECTS??? **/

  /* Compute the total size of the blasted object */
    for (i = 0, numArenas = 0, totSzB = 0;  i < NUM_ARENAS;  i++) {
	if (totArenaSzB[i] > 0) {
	    numArenas++;
	    totSzB += totArenaSzB[i];
	}
    }
    totSzB += (sizeof(ml_image_hdr_t) + sizeof(ml_blast_hdr_t)
		+ (numArenas * sizeof(heap_arena_hdr_t)));
    /** COUNT SPACE FOR BIG OBJECTS **/

  /* include the space for the external symbols */
    totSzB += sizeof(extern_tbl_hdr_t) + ExportTableSz(info->exportTbl);

  /* allocate the heap object for the blasted representation, and initialize
   * the writer.
   */
    blastedObj = AllocBlastData (msp, totSzB);
    wr = WR_OpenMem (PTR_MLtoC(Byte_t, blastedObj), totSzB);

  /* initialize the arena headers */
    arenaHdrSz = numArenas * sizeof(heap_arena_hdr_t);
    arenaHdrsBuf = (heap_arena_hdr_t *) MALLOC (arenaHdrSz);
    for (p = arenaHdrsBuf, i = 0;  i < NUM_ARENAS;  i++) {
	if (totArenaSzB[i] > 0) {
	    p->gen		    = 0;
	    p->objKind		    = i;
	    p->info.o.baseAddr	    = 0;   /* not used */
	    p->info.o.sizeB	    = totArenaSzB[i];
	    p->info.o.roundedSzB    = -1;  /* not used */
	    p->offset		    = -1;  /* not used */
	    arenaHdrs[i]	    = p;
	    p++;
	}
	else
	    arenaHdrs[i] = NIL(heap_arena_hdr_t *);
    }
    /** WHAT ABOUT BIG OBJECTS **/

  /* blast out the image header */
    if (HeapIO_WriteImageHeader (wr, BLAST_IMAGE) == FAILURE) {
	FREE (arenaHdrsBuf);
	return BLAST_ERROR;
    }

  /* blast out the blast header */
    {
	ml_blast_hdr_t	hdr;

	hdr.numArenas = numArenas;
	hdr.numBOKinds = 0; /** FIX THIS **/
	hdr.numBORegions = 0;   /** FIX THIS **/

	if (isEXTERNTAG(obj)) {
	    ASSERT(numArenas == 0);
	    hdr.rootObj = obj;
	}
	else {
	    aid_t	aid = ADDR_TO_PAGEID(BIBOP, obj);

	    if (IS_BIGOBJ_AID(aid)) {
		embobj_info_t	*p = FindEmbObj(info->embobjTbl, obj);

		if ((p == NIL(embobj_info_t *)) || (p->kind == USED_CODE)) {
		    Error ("blasting big objects not implemented\n");
		    FREE (arenaHdrsBuf);
		    return BLAST_ERROR;
		}
		else
		    hdr.rootObj = p->relAddr;
	    }
	    else {
		Addr_t	addr = PTR_MLtoADDR(obj);
		int	gen = EXTRACT_GEN(aid) - 1;
		int	kind = EXTRACT_OBJC(aid) - 1;
		addr -= adjust[gen][kind].base;
		addr += adjust[gen][kind].offset;
		hdr.rootObj = HIO_TAG_PTR(kind, addr);
	    }
	}

	WR_Write(wr, &hdr, sizeof(hdr));
	if (WR_Error(wr)) {
	    FREE (arenaHdrsBuf);
	    return BLAST_ERROR;
	}
    }

  /* blast out the externals table */
    if (HeapIO_WriteExterns(wr, info->exportTbl) == -1) {
	FREE (arenaHdrsBuf);
	return BLAST_ERROR;
    }

  /* blast out the arena headers */
    WR_Write (wr, arenaHdrsBuf, arenaHdrSz);
    if (WR_Error(wr)) {
	FREE (arenaHdrsBuf);
	return BLAST_ERROR;
    }

  /* blast out the heap itself */
    for (i = 0;  i < NUM_ARENAS;  i++) {
	if (i == STRING_INDX) {
	  /* blast out the embedded literals */
	    BlastGC_BlastLits (wr);
	  /* blast out the rest of the strings */
	    for (j = 0;  j < maxGen;  j++) {
		arena_t	*ap = heap->gen[j]->arena[i];
		if (isACTIVE(ap)) {
		    WR_Write(wr, ap->tospBase,
			(Addr_t)(ap->nextw)-(Addr_t)(ap->tospBase));
		}
	    } /* end for */
	}
	else {
	    for (j = 0;  j < maxGen;  j++) {
		arena_t	*ap = heap->gen[j]->arena[i];
		ml_val_t	*p, *top;
		if (isACTIVE(ap)) {
		    for (p = ap->tospBase, top = ap->nextw;  p < top;  p++) {
			ml_val_t	w = *p;
			if (isBOXED(w)) {
			    aid_t		aid = ADDR_TO_PAGEID(BIBOP, w);
			    if (isUNMAPPED(aid)) {
				w = ExportCSymbol(info->exportTbl, w);
				ASSERT (w != ML_unit);
			    }
			    else if (IS_BIGOBJ_AID(aid)) {
				embobj_info_t	*objInfo
						    = FindEmbObj(info->embobjTbl, w);

				if ((objInfo == NIL(embobj_info_t *))
				|| (objInfo->kind == USED_CODE))
				    Die("blast bigobj unimplemented");
				else
				    w = objInfo->relAddr;
			    }
			    else {
			      /* adjust the pointer */
				int		gen = EXTRACT_GEN(aid)-1;
				int		kind = EXTRACT_OBJC(aid)-1;
				Addr_t	addr = PTR_MLtoADDR(w);
				addr -= adjust[gen][kind].base;
				addr += adjust[gen][kind].offset;
				w = HIO_TAG_PTR(kind, addr);
			    }
			}
			WR_Put(wr, (Word_t)w);
		    }
		}
	    } /* end for */
	}
    }

    FREE (arenaHdrsBuf);

    if (WR_Error(wr))
	return BLAST_ERROR;
    else {
	SEQHDR_ALLOC (msp, blastedObj, DESC_string, blastedObj, totSzB);
	return blastedObj;
    }

} /* end of BlastHeap */


/* AllocBlastData:
 *
 * Allocate some heap memory for blasting an object.
 */
PVT ml_val_t AllocBlastData (ml_state_t *msp, Addr_t sizeB)
{
    heap_t	    *heap = msp->ml_heap;
    int		    nWords = BYTES_TO_WORDS(sizeB);
    ml_val_t	    desc = MAKE_DESC(nWords, DTAG_raw32);
    ml_val_t	    res;

/** we probably should allocate space in the big-object region for these objects **/
    if (sizeB < heap->allocSzB-(8*ONE_K)) {
	ML_AllocWrite (msp, 0, desc);
	res = ML_Alloc (msp, nWords);
	return res;
    }
    else {
	Die ("blasting out of %d bytes not supported yet!  Increase allocation arena size.", sizeB);
    }

} /* end of AllocBlastData */


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