Bug fixes and made faster on PDP-11

This commit is contained in:
ceriel 1987-04-08 17:15:30 +00:00
parent 53a6ded473
commit 0177bf59ff
4 changed files with 143 additions and 81 deletions

View file

@ -105,21 +105,21 @@ handle_relos(head, sects, names)
} }
} else { } else {
for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) { for (sectindex = 0; sectindex < head->oh_nsect; sectindex++) {
emit = getemit(head, sects, sectindex);
nrelo = head->oh_nrelo; startrelo(head);
while (nrelo--) {
relo = nextrelo();
if (relo->or_sect - S_MIN == sectindex) {
relocate(head,emit,names,relo);
/*
* Write out the (probably changed)
* relocation information.
*/
if (flagword & RFLAG)
wr_relo(relo, 1);
}
}
if (sects[sectindex].os_flen) { if (sects[sectindex].os_flen) {
emit = getemit(head, sects, sectindex);
nrelo = head->oh_nrelo; startrelo(head);
while (nrelo--) {
relo = nextrelo();
if (relo->or_sect - S_MIN == sectindex) {
relocate(head,emit,names,relo);
/*
* Write out the (probably changed)
* relocation information.
*/
if (flagword & RFLAG)
wr_relo(relo, 1);
}
}
wrt_nulls(sectindex, zeros[sectindex]); wrt_nulls(sectindex, zeros[sectindex]);
zeros[sectindex] = 0; zeros[sectindex] = 0;
wrt_emit(emit, sectindex, sects[sectindex].os_flen); wrt_emit(emit, sectindex, sects[sectindex].os_flen);
@ -138,17 +138,22 @@ handle_relos(head, sects, names)
*/ */
static static
put_locals(name, nnames) put_locals(name, nnames)
register struct outname *name; struct outname *name;
register ushort nnames; register ushort nnames;
{ {
register struct outname *oname = name;
register struct outname *iname = oname;
while (nnames--) { while (nnames--) {
if ((name->on_type & S_EXT) == 0 && mustsavelocal(name)) { if ((iname->on_type & S_EXT) == 0 && mustsavelocal(iname)) {
namerelocate(name); namerelocate(iname);
addbase(name); addbase(iname);
wrt_name(name); wrt_name(iname, 0);
*oname++ = *iname;
} }
name++; iname++;
} }
wr_name(name, oname - name);
} }
/* /*

View file

@ -31,14 +31,12 @@ static copy_down();
static copy_up(); static copy_up();
static free_saved_moduls(); static free_saved_moduls();
static writelong(); static writelong();
static namecpy();
struct memory mems[NMEMS]; struct memory mems[NMEMS];
bool incore = TRUE; /* TRUE while everything can be kept in core. */ bool incore = TRUE; /* TRUE while everything can be kept in core. */
ind_t core_position = (ind_t)0; /* Index of current module. */ ind_t core_position = (ind_t)0; /* Index of current module. */
#define AT_LEAST (ind_t)2 /* See comment about string areas. */
#define GRANULE 64 /* power of 2 */ #define GRANULE 64 /* power of 2 */
static char *BASE; static char *BASE;
@ -78,28 +76,39 @@ init_core()
extern char *sbrk(); extern char *sbrk();
#include "mach.c" #include "mach.c"
#define ALIGN 8 /* minimum alignment for pieces */
#define AT_LEAST (ind_t)2*ALIGN /* See comment about string areas. */
total_size = (ind_t)0; /* Will accumulate the sizes. */ total_size = (ind_t)0; /* Will accumulate the sizes. */
BASE = base = sbrk(0); /* First free. */ BASE = base = sbrk(0); /* First free. */
for (mem = mems; mem < &mems[NMEMS]; mem++) { if ((int)base % ALIGN) {
mem->mem_base = base; base = sbrk(ALIGN - (int)base % ALIGN);
mem->mem_full = (ind_t)0; BASE = base = sbrk(0);
base += mem->mem_left; /* Each piece will start after prev. */
total_size += mem->mem_left;
} }
/* /*
* String areas are special-cased. The first byte is unused as a way to * String areas are special-cased. The first byte is unused as a way to
* distinguish a name without string from a name which has the first * distinguish a name without string from a name which has the first
* string in the string area. * string in the string area.
*/ */
if (mems[ALLOLCHR].mem_left == 0) for (mem = mems; mem < &mems[NMEMS]; mem++) {
total_size += 1; mem->mem_base = base;
else mem->mem_full = (ind_t)0;
mems[ALLOLCHR].mem_left -= 1; if (mem == &mems[ALLOLCHR] || mem == &mems[ALLOGCHR]) {
if (mems[ALLOGCHR].mem_left == 0) if (mem->mem_left == 0) {
total_size += 1; mem->mem_left = ALIGN;
else total_size += ALIGN;
mems[ALLOGCHR].mem_left -= 1; base += ALIGN;
}
base += mem->mem_left;
total_size += mem->mem_left;
mem->mem_left--;
mem->mem_full++;
}
else {
base += mem->mem_left; /* Each piece will start after prev. */
total_size += mem->mem_left;
}
}
if (sbreak(total_size) == -1) { if (sbreak(total_size) == -1) {
incore = FALSE; /* In core strategy failed. */ incore = FALSE; /* In core strategy failed. */
@ -109,13 +118,17 @@ init_core()
base = BASE; base = BASE;
for (mem = mems; mem < &mems[NMEMS]; mem++) { for (mem = mems; mem < &mems[NMEMS]; mem++) {
mem->mem_base = base; mem->mem_base = base;
mem->mem_full = (ind_t)0; if (mem == &mems[ALLOLCHR] || mem == &mems[ALLOGCHR]) {
mem->mem_left = 0; base += ALIGN;
mem->mem_left = ALIGN - 1;
mem->mem_full = 1;
}
else {
mem->mem_full = (ind_t)0;
mem->mem_left = 0;
}
} }
} }
mems[ALLOLCHR].mem_full = 1;
mems[ALLOGCHR].mem_full = 1;
} }
/* /*
@ -160,7 +173,7 @@ compact(piece, incr, flag)
{ {
register ind_t gain, size; register ind_t gain, size;
register struct memory *mem; register struct memory *mem;
#define ALIGN 8 /* minimum alignment for pieces */ int min = piece, max = piece;
#define SHIFT_COUNT 2 /* let pieces only contribute if their free #define SHIFT_COUNT 2 /* let pieces only contribute if their free
memory is more than 1/2**SHIFT_COUNT * 100 % memory is more than 1/2**SHIFT_COUNT * 100 %
of its occupied memory of its occupied memory
@ -170,35 +183,79 @@ compact(piece, incr, flag)
for (mem = &mems[0]; mem < &mems[NMEMS - 1]; mem++) { for (mem = &mems[0]; mem < &mems[NMEMS - 1]; mem++) {
assert(mem->mem_base + mem->mem_full + mem->mem_left == (mem+1)->mem_base); assert(mem->mem_base + mem->mem_full + mem->mem_left == (mem+1)->mem_base);
} }
mem = &mems[piece];
if (flag == NORMAL) {
/* try and gain a bit more than needed */
gain = (mem->mem_full + incr) >> SHIFT_COUNT;
if (incr < gain) incr = gain;
}
/* /*
* First, check that moving will result in enough space * First, check that moving will result in enough space
*/ */
if (flag != FREEZE) { if (flag != FREEZE) {
gain = mems[piece].mem_left & ~(ALIGN - 1); gain = mem->mem_left;
for (mem = &mems[0]; mem <= &mems[NMEMS-1]; mem++) { for (mem = &mems[piece-1]; mem >= &mems[0]; mem--) {
/* /*
* Don't give it all away! * Don't give it all away!
* If this does not give us enough, bad luck * If this does not give us enough, bad luck
*/ */
if (mem == &mems[piece]) continue;
if (flag == FORCED) if (flag == FORCED)
size = 0; size = 0;
else size = mem->mem_full >> SHIFT_COUNT; else {
if (mem->mem_left > size) size = mem->mem_full >> SHIFT_COUNT;
if (size == 0) size = mem->mem_left >> 1;
}
if (mem->mem_left >= size)
gain += (mem->mem_left - size) & ~(ALIGN - 1); gain += (mem->mem_left - size) & ~(ALIGN - 1);
if (gain >= incr) {
min = mem - &mems[0];
break;
}
}
if (min == piece)
for (mem = &mems[piece+1]; mem <= &mems[NMEMS - 1]; mem++) {
/*
* Don't give it all away!
* If this does not give us enough, bad luck
*/
if (flag == FORCED)
size = 0;
else {
size = mem->mem_full >> SHIFT_COUNT;
if (size == 0) size = mem->mem_left >> 1;
}
if (mem->mem_left >= size)
gain += (mem->mem_left - size) & ~(ALIGN - 1);
if (gain >= incr) {
max = mem - &mems[0];
break;
}
}
if (min == piece) {
min = 0;
if (max == piece) max = 0;
} }
if (gain < incr) return 0; if (gain < incr) return 0;
} }
else {
min = 0;
max = NMEMS - 1;
}
gain = 0; gain = 0;
for (mem = &mems[0]; mem != &mems[piece]; mem++) { for (mem = &mems[min]; mem != &mems[piece]; mem++) {
/* Here memory is inserted before a piece. */ /* Here memory is inserted before a piece. */
assert(passnumber == FIRST || gain == (ind_t)0); assert(passnumber == FIRST || gain == (ind_t)0);
copy_down(mem, gain); if (gain) copy_down(mem, gain);
if (flag == FREEZE || gain < incr) { if (flag == FREEZE || gain < incr) {
if (flag != NORMAL) size = 0; if (flag != NORMAL) size = 0;
else size = mem->mem_full >> SHIFT_COUNT; else {
if (mem->mem_left > size) { size = mem->mem_full >> SHIFT_COUNT;
if (size == 0) size = mem->mem_left >> 1;
}
if (mem->mem_left >= size) {
size = (mem->mem_left - size) & ~(ALIGN - 1); size = (mem->mem_left - size) & ~(ALIGN - 1);
gain += size; gain += size;
mem->mem_left -= size; mem->mem_left -= size;
@ -208,25 +265,28 @@ compact(piece, incr, flag)
/* /*
* Now mems[piece]: * Now mems[piece]:
*/ */
copy_down(mem, gain); if (gain) copy_down(mem, gain);
gain += mem->mem_left & ~(ALIGN - 1); gain += mem->mem_left;
mem->mem_left &= (ALIGN - 1); mem->mem_left = 0;
if (gain < incr) { if (gain < incr) {
register ind_t up = (ind_t)0; register ind_t up = (ind_t)0;
for (mem = &mems[NMEMS - 1]; mem > &mems[piece]; mem--) { for (mem = &mems[max]; mem > &mems[piece]; mem--) {
/* Here memory is appended after a piece. */ /* Here memory is appended after a piece. */
if (flag == FREEZE || gain + up < incr) { if (flag == FREEZE || gain + up < incr) {
if (flag == FREEZE) size = 0; if (flag != NORMAL) size = 0;
else size = mem->mem_full >> SHIFT_COUNT; else {
if (mem->mem_left > size) { size = mem->mem_full >> SHIFT_COUNT;
if (size == 0) size = mem->mem_left >> 1;
}
if (mem->mem_left >= size) {
size = (mem->mem_left - size) & ~(ALIGN - 1); size = (mem->mem_left - size) & ~(ALIGN - 1);
up += size; up += size;
mem->mem_left -= size; mem->mem_left -= size;
} }
} }
copy_up(mem, up); if (up) copy_up(mem, up);
} }
gain += up; gain += up;
} }
@ -253,7 +313,6 @@ copy_down(mem, dist)
register char *new; register char *new;
register ind_t size; register ind_t size;
if (!dist) return;
size = mem->mem_full; size = mem->mem_full;
old = mem->mem_base; old = mem->mem_base;
new = old - dist; new = old - dist;
@ -277,7 +336,6 @@ copy_up(mem, dist)
register char *new; register char *new;
register ind_t size; register ind_t size;
if (!dist) return;
size = mem->mem_full; size = mem->mem_full;
old = mem->mem_base + size; old = mem->mem_base + size;
new = old + dist; new = old + dist;
@ -312,7 +370,7 @@ alloc(piece, size)
while (left + incr < size) while (left + incr < size)
incr += INCRSIZE; incr += INCRSIZE;
if (incr == 0 || if (incr == 0 ||
(incr < left + full && move_up(piece, left + full)) || (incr < left + full && move_up(piece, left + full)) ||
move_up(piece, incr) || move_up(piece, incr) ||
@ -340,9 +398,7 @@ hard_alloc(piece, size)
if (size != (ind_t)size) if (size != (ind_t)size)
return BADOFF; return BADOFF;
alloctype = FORCED;
if ((ret = alloc(piece, size)) != BADOFF) { if ((ret = alloc(piece, size)) != BADOFF) {
alloctype = NORMAL;
return ret; return ret;
} }
@ -364,6 +420,11 @@ hard_alloc(piece, size)
} }
free_saved_moduls(); free_saved_moduls();
if ((ret = alloc(piece, size)) != BADOFF) {
return ret;
}
alloctype = FORCED;
ret = alloc(piece, size); ret = alloc(piece, size);
alloctype = NORMAL; alloctype = NORMAL;
return ret; return ret;
@ -516,7 +577,6 @@ write_bytes()
wr_close(); wr_close();
} }
static
namecpy(name, nname, offchar) namecpy(name, nname, offchar)
register struct outname *name; register struct outname *name;
register ushort nname; register ushort nname;

View file

@ -343,7 +343,7 @@ putdbugindex(dbugoff, ndbugbytes)
ind_t dbugindex; ind_t dbugindex;
extern ind_t alloc(); extern ind_t alloc();
if ((dbugindex = alloc(ALLORELO, ndbugbytes)) != BADOFF) { if ((dbugindex = alloc(ALLODBUG, ndbugbytes)) != BADOFF) {
*(ind_t *)modulptr(dbugoff) = dbugindex; *(ind_t *)modulptr(dbugoff) = dbugindex;
return TRUE; return TRUE;
} }
@ -501,6 +501,7 @@ modulsize(head)
static struct outrelo *walkrelo; static struct outrelo *walkrelo;
static unsigned short cnt_relos; static unsigned short cnt_relos;
static unsigned short index; static unsigned short index;
#define _RELSIZ 64
startrelo(head) startrelo(head)
register struct outhead *head; register struct outhead *head;
@ -512,7 +513,7 @@ startrelo(head)
walkrelo = (struct outrelo *)address(ALLORELO, reloindex); walkrelo = (struct outrelo *)address(ALLORELO, reloindex);
} }
else { else {
index = 20; index = _RELSIZ;
rd_rew_relos(head); rd_rew_relos(head);
cnt_relos = head->oh_nrelo; cnt_relos = head->oh_nrelo;
} }
@ -521,13 +522,13 @@ startrelo(head)
struct outrelo * struct outrelo *
nextrelo() nextrelo()
{ {
static struct outrelo relobuf[20]; static struct outrelo relobuf[_RELSIZ];
if (incore) if (incore)
return walkrelo++; return walkrelo++;
if (index == 20) { if (index == _RELSIZ) {
int i = cnt_relos >= 20 ? 20 : cnt_relos; int i = cnt_relos >= _RELSIZ ? _RELSIZ : cnt_relos;
cnt_relos -= i; cnt_relos -= i;
rd_relo(relobuf, i); rd_relo(relobuf, i);

View file

@ -65,23 +65,19 @@ end_write()
register struct outname *name; register struct outname *name;
register int sectindex; register int sectindex;
extern ushort NGlobals; extern ushort NGlobals;
extern long NGChars;
assert(!incore); assert(!incore);
assert(!(flagword & SFLAG)); assert(!(flagword & SFLAG));
cnt = NGlobals; cnt = NGlobals;
name = (struct outname *)address(ALLOGLOB, (ind_t)0); name = (struct outname *)address(ALLOGLOB, (ind_t)0);
while (cnt--) { namecpy(name, NGlobals, off_char);
if (name->on_foff != (long)0) { wr_name(name, NGlobals);
name->on_mptr = address(ALLOGCHR, (ind_t)name->on_foff); wr_string(mems[ALLOGCHR].mem_base+1, NGChars);
} else { off_char += NGChars;
name->on_mptr = (char *)0;
}
wrt_name(name);
name++;
}
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++) for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++)
wrt_name(sectname(sectindex)); wrt_name(sectname(sectindex), 1);
} }
wrt_emit(emit, sectindex, cnt) wrt_emit(emit, sectindex, cnt)
@ -107,7 +103,7 @@ wrt_nulls(sectindex, cnt)
} }
} }
wrt_name(name) wrt_name(name, writename)
register struct outname *name; register struct outname *name;
{ {
assert(!incore); assert(!incore);
@ -121,5 +117,5 @@ wrt_name(name)
} else { } else {
name->on_foff = (long)0; name->on_foff = (long)0;
} }
wr_name(name, 1); if (writename) wr_name(name, 1);
} }