Personal tools
You are here: Home Projects C++ Cfront releases Release 1.0 Source cfront src alloc.c
Document Actions

alloc.c

by Paul McJones last modified 2007-02-02 09:34

Click here to get the file

Size 3.3 kB - File type text/x-csrc

File contents

/* @(#) alloc.c 1.3 1/27/86 17:48:32 */ 
/*ident	"@(#)cfront:src/alloc.c	1.3" */
#include "cfront.h"

extern void free(char*);
extern char *malloc(unsigned);
extern void print_free();

typedef class header HEADER;

static HEADER *morecore(unsigned);

int maxalloc = 0;	// largest object allocated

class header {	/* free block header */
public:
	HEADER	*next;	/* next free block */
	unsigned size;	/* size of this free block */
};

static HEADER base;	/* empty list to get started */
HEADER *allocp = NULL;	/* last allocated block */

void print_free()
{
	register HEADER* p, *q = 0;
	register int amount = 0;
	register int number = 0;

	for (p=allocp; q!=allocp; q=p=p->next) {
		number++;
		amount += p->size;
	}
	fprintf(stderr,"print_free: %d %d\n",number,amount*sizeof(HEADER) );
}

char *malloc(unsigned nbytes)	/* general-purpose storage allocator */
{
	register HEADER *p, *q;
	register int nunits;

	Nalloc++;
	nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
	if ((q = allocp) == NULL) {	/* no free list yet */
		base.next = allocp = q = &base;
		base.size = 0;
	}
	for (p=q->next; ; q=p, p=p->next) {
		if (p->size >= nunits) {	/* big enough */
			if (p->size == nunits)	/* exactly */
				q->next = p->next;
			else {	/* allocate tail end */
				p->size -= nunits;
				p += (int)p->size;
				p->size = nunits;
			}
			allocp = q;

//error('d',"malloc(%d %d)->%d %d\n",nbytes,nunits*sizeof(HEADER),p+1,p+nunits);
			if (maxalloc < nunits) maxalloc = nunits;

			register int* x = (int*)(p+1);
	 		register int* y = (int*)(p+nunits);
			while (x < y) *--y = 0;
			return (char*) x;
		}
		if (p == allocp)  /* wrapped around free list */
			if ((p = morecore(nunits)) == NULL)
				return(NULL);	/* none left */
	}
}

#define	NALLOC	1024	/* #units to allocate at once */

static HEADER *morecore(unsigned nu)	/* ask system for memory */
{
	extern char *sbrk(int);
	register HEADER *up;
	register int rnu2;
	
	register int rnu = NALLOC * ((nu+NALLOC-1) / NALLOC);
	register char* cp = sbrk(rnu2 = rnu*sizeof(HEADER));
	Nfree_store += rnu2;
	if ((int)cp == -1) error('i',"free store exhausted");	// no space at all
	up = (HEADER*)cp;
	up->size = rnu;
	int ma = maxalloc;
	maxalloc = rnu;
	free((char*)(up+1));	// put it on the free list
	maxalloc = ma;
	return allocp;
}

int NFn, NFtn, NFbt, NFpv, NFf, NFe, NFs, NFc;

void free(char* ap)		/* put block on free list */
{
	if (ap == 0) return;

	register HEADER* p = (HEADER*)ap - 1;	/* point to header */

	if (maxalloc < p->size) error('i',"free store corrupted (%d)",ap);

	Nfree++;

if (Nspy) {
	Pname pp = (Pname) ap;
	TOK t = pp->base;
	char* s = 0;

	switch (t) {

	case INT: case CHAR: case TYPE: case VOID: case SHORT: case LONG:
	case FLOAT: case DOUBLE: case COBJ: case EOBJ: case FIELD:
			NFbt++; break;

	case PTR: case VEC:
			NFpv++; break;

	case FCT:	NFf++; break;

	case ICON: case CCON: case STRING: case FCON: case THIS:
			NFc++; break;
	}
}
	for ( register HEADER* q=allocp; !(p > q && p < q->next); q=q->next)
		if (q >= q->next && (p > q || p < q->next))
			break;	/* at one end or other */

	if (p+p->size == q->next) { /* join to upper nbr */
		p->size += q->next->size;
		p->next = q->next->next;
	} else
		p->next = q->next;
	if (q+q->size == p) {	/* join to lower nbr */
		q->size += p->size;
		q->next = p->next;
	} else
		q->next = p;
	allocp = q;
}
« May 2013 »
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: