Bug and patch
Gilles Dauphin
dauphin at sig.enst.fr
Fri Mar 14 03:20:55 PST 1997
Hi,
I think some code is wrong in the assembler code of Sparc/Kaffe:
file : config/sparc/threads.h
#define THREADSWITCH(to, from) { \
...
ld [%1],%2 \n\
ld [%2+16],%%i7 \n\
ld [%2+12],%%l7 <-- this produce incorrecte code.
and is translate with gcc -S by:
ld [%l7+12],%l7 <---- gloups!
I think , here is the equivalent correct assembler code for native compiler:
void ThreadSwitch( ctx * to, ctx * from )
{
int regstore[6];
register int *reg; /* %i5 */
register uint8 ** frp; /* %i4 */
register uint8 ** trp; /* %i3 */
reg = regstore; /* avoid compiler optimisation */
frp = &((from)->restorePoint);
trp = &((to)->restorePoint);
asm(" \n\
call 1f \n\
nop \n\
1: \n\
add %o7,%lo(2f-1b+8),%l0 \n\
\n\
ta 3 \n\
st %l0,[%i5+0] \n\
st %fp,[%i5+4] \n\
st %sp,[%i5+8] \n\
st %i5,[%i5+12] \n\
st %i7,[%i5+16] \n\
st %i5,[%i4] \n\
\n\
ld [%i3],%l0 \n\
ld [%l0+16],%i7 \n\
ld [%l0+12],%i5 \n\ <-- good !
ld [%l0+8],%sp \n\
ld [%l0+4],%fp \n\
ld [%l0+0],%l0 \n\
\n\
jmpl %l0,%g0 \n\
nop \n\
2: nop"
);
}
Now I have a kaffe compiled with native compiler (kaffe interpreter only).
I check for memory access and discover other bug :
In file kaffe/kaffevm/constants.c:
-------------------------------------
void
readConstantPool(Class* this, classFile* fp)
{
constants* info = CLASS_CONSTANTS (this);
ConstSlot* pool;
u1* tags;
int i;
u1 type;
u2 len;
u2 d2, d2b;
u4 d4, d4b;
bool error;
readu2(&info->size, fp);
RDBG( printf("constant_pool_count=%d\n", info->size); )
/* Allocate space for tags and data */
pool = gc_malloc((sizeof(ConstSlot) + sizeof(u1)) * info->size, GC_NORMAL);
tags = (u1*)&pool[info->size];
GC_WRITE(this, pool);
info->data = pool;
info->tags = tags;
error = false;
pool[0] = 0;
tags[0] = CONSTANT_Unknown;
for (i = 1; i < info->size; i++) {
readu1(&type, fp);
RDBG( printf("Constant type %d\n", type); )
tags[i] = type;
switch (type) {
case CONSTANT_Utf8:
readu2(&len, fp);
PROBLEM HERE-->>> pool[i] = (ConstSlot) makeUtf8Const (fp->buf, len);
fp->buf += len;
break;
---------------------------------------------
Some is wrong whith code in file gc-incremental.c
-------------------------------
void
walkObject(gcInfo* base)
{
void** mem;
gcInfo* obj;
int32 i;
assert(base->colour == GC_GREY);
base->colour = GC_BLACK;
if (base->final != GC_ROOT) {
REMOVELIST(base);
APPENDLIST(black, base);
}
gcStats.markedobj += 1;
gcStats.markedmem += base->size;
DBG( printf("walkObject: %d %x-%x\n", base->ref, GC2MEM(base),
GC2MEM(base)+base->size);fflush(stdout); )
mem = GC2MEM(base);
for (i = (base->size / sizeof(void*)) - 1; i >= 0; i--) {
obj = MEM2GC(mem[i]); <---- PROBLEM HERE
/* Check we've got a valid object */
if (((void*)obj < minMem || (void*)obj > maxMem) ||
(((uintp)obj % sizeof(void*)) != 0) ||
(!VALIDREF(obj->ref)) || <------PROBLEM HERE
(GETREF(obj->ref) != (uintp)obj)) { <-----PROBLEM HERE
continue;
}
-------------
MEM2GC is macro :
#define MEM2GC(_m) ((gcInfo*)(((uint8*)(_m)) - sizeof(gcInfo)))
You are assuming in function readConstantPool that a pool of Constant
have *one* gcInfo, and in function walkObject you say that *each* Constant
have a gcInfo.
Maybe i am wrong. But when checking this code, debugger say there is problem.
Any body suggest a patch for this?
Thank's
Gilles
More information about the kaffe
mailing list