/* BobDumpHeap - dump the contents of the bob heap */ void BobDumpHeap(BobInterpreter *c) { unsigned char *scan; /* first collect the garbage */ //BobCollectGarbage(c); /* dump each heap object */ scan = c->newSpace->base; while (scan < c->newSpace->free) { BobValue val = (BobValue)scan; scan += ValueSize(val); //if (BobCObjectP(val)) { BobPrint(c,val,c->standardOutput); BobStreamPutC('\n',c->standardOutput); //} } }
/* BobDefaultCopy - copy an object from old space to new space */ BobValue BobDefaultCopy(BobInterpreter *c,BobValue obj) { long size = ValueSize(obj); BobValue newObj; /* don't copy an object that is already in new space */ if (NewObjectP(c,obj)) return obj; /* find a place to put the new object */ newObj = (BobValue)c->newSpace->free; /* copy the object */ memcpy(newObj,obj,(size_t)size); c->newSpace->free += size; /* store a forwarding address in the old object */ BobSetDispatch(obj,&BobBrokenHeartDispatch); BobBrokenHeartSetForwardingAddr(obj,newObj); /* return the new object */ return newObj; }
/* BobCollectGarbage - garbage collect a heap */ void BobCollectGarbage(BobInterpreter *c) { BobProtectedPtrs *ppb; unsigned char *scan; BobMemorySpace *ms; BobDispatch *d; BobValue obj; BobStreamPutS("[GC",c->standardError); /* reverse the memory spaces */ ms = c->oldSpace; c->oldSpace = c->newSpace; c->newSpace = ms; ms->free = ms->base; /* copy the root objects */ c->nilValue = BobCopyValue(c,c->nilValue); c->trueValue = BobCopyValue(c,c->trueValue); c->falseValue = BobCopyValue(c,c->falseValue); c->symbols = BobCopyValue(c,c->symbols); c->objectValue = BobCopyValue(c,c->objectValue); /* copy basic types */ c->methodObject = BobCopyValue(c,c->methodObject); c->vectorObject = BobCopyValue(c,c->vectorObject); c->symbolObject = BobCopyValue(c,c->symbolObject); c->stringObject = BobCopyValue(c,c->stringObject); c->integerObject = BobCopyValue(c,c->integerObject); #ifdef BOB_INCLUDE_FLOAT_SUPPORT c->floatObject = BobCopyValue(c,c->floatObject); #endif /* copy the type list */ for (d = c->types; d != NULL; d = d->next) { if (d->object) d->object = BobCopyValue(c,d->object); } /* copy protected pointers */ for (ppb = c->protectedPtrs; ppb != NULL; ppb = ppb->next) { BobValue **pp = ppb->pointers; int count = ppb->count; for (; --count >= 0; ++pp) **pp = BobCopyValue(c,**pp); } /* copy the stack */ BobCopyStack(c); /* copy the current code object */ if (c->code) c->code = BobCopyValue(c,c->code); /* copy the registers */ c->val = BobCopyValue(c,c->val); c->env = BobCopyValue(c,c->env); /* copy any user objects */ if (c->protectHandler) (*c->protectHandler)(c,c->protectData); /* scan and copy until all accessible objects have been copied */ scan = c->newSpace->base; while (scan < c->newSpace->free) { obj = (BobValue)scan; #if 0 BobStreamPutS("Scanning ",c->standardOutput); BobPrint(c,obj,c->standardOutput); BobStreamPutC('\n',c->standardOutput); #endif scan += ValueSize(obj); ScanValue(c,obj); } /* fixup cbase and pc */ if (c->code) { long pcoff = c->pc - c->cbase; c->cbase = BobStringAddress(BobCompiledCodeBytecodes(c->code)); c->pc = c->cbase + pcoff; } /* count the garbage collections */ ++c->gcCount; { char buf[128]; sprintf(buf, " - %lu bytes free out of %lu, collections %lu]\n", (unsigned long)(c->newSpace->top - c->newSpace->free), (unsigned long)(c->newSpace->top - c->newSpace->base), (unsigned long)c->gcCount); BobStreamPutS(buf,c->standardError); } /* destroy any unreachable cobjects */ BobDestroyUnreachableCObjects(c); }
extern LargeByteString * ValueToLBS( ValueStruct *val, char *codeset) { byte work[SIZE_NUMBUF+1]; byte work2[SIZE_NUMBUF+2]; byte *p , *q; int i; int size; LargeByteString *ret; ENTER_FUNC; if ( val == NULL ) { ret = NULL; } else { dbgprintf("type = %X\n",(int)ValueType(val)); if ( ValueStr(val) == NULL ) { ValueStr(val) = NewLBS(); } LBS_EmitStart(ValueStr(val)); if ( IS_VALUE_NIL(val) ) { LBS_EmitChar(ValueStr(val),CHAR_NIL); } else switch (ValueType(val)) { case GL_TYPE_CHAR: case GL_TYPE_VARCHAR: case GL_TYPE_TEXT: case GL_TYPE_SYMBOL: case GL_TYPE_DBCODE: if ( ValueString(val) != NULL ) { RewindLBS(ValueStr(val)); if ( IS_VALUE_EXPANDABLE(val) ) { LBS_EmitStringCodeset(ValueStr(val),ValueString(val), ValueStringSize(val), ValueStringLength(val),codeset); if ( ( size = ValueStringLength(val) - ValueSize(val) ) > 0 ) { for ( ; size > 0 ; size -- ) { LBS_EmitChar(ValueStr(val),0); } } } else { LBS_EmitStringCodeset(ValueStr(val),ValueString(val), ValueStringSize(val), 0,codeset); } } break; case GL_TYPE_BYTE: case GL_TYPE_BINARY: #ifdef BINARY_IS_BASE64 size = ( ( ValueByteLength(val) + 2 ) / 3 ) * 4; p = (char *)xmalloc(size); size = EncodeBase64(p,size,ValueByte(val),ValueByteLength(val)); LBS_ReserveSize(ValueStr(val),size+1); strcpy(ValueStrBody(val),p); xfree(p); #else p = ValueByte(val); for ( i = 0 ; i < ValueByteLength(val) ; i ++ , p ++ ) { switch (*p) { case '\\': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'\\'); break; case '"': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'"'); break; case '/': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'/'); break; case '\b': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'b'); break; case '\f': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'f'); break; case '\n': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'n'); break; case '\r': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'r'); break; case '\t': LBS_EmitChar(ValueStr(val),'\\'); LBS_EmitChar(ValueStr(val),'t'); break; default: if ( isprint(*p) ) { LBS_EmitChar(ValueStr(val),*p); } else { sprintf(work,"\\u%02X",(int)*p); LBS_EmitString(ValueStr(val),work); } break; } } if ( ( size = ValueStringLength(val) - ValueSize(val) ) > 0 ) { for ( ; size > 0 ; size -- ) { LBS_EmitByte(ValueStr(val),0); } } #endif break; case GL_TYPE_NUMBER: strcpy(work,ValueFixedBody(val)); p = work; q = work2; if ( *p >= 0x70 ) { *q ++ = '-'; *p ^= 0x40; } strcpy(q,p); if ( ValueFixedSlen(val) > 0 ) { p = work2 + strlen(work2); *(p + 1) = 0; q = p - 1; for ( i = 0 ; i < ValueFixedSlen(val) ; i ++ ) { *p -- = *q --; } *p = '.'; } LBS_EmitString(ValueStr(val),work2); break; case GL_TYPE_INT: sprintf(work,"%d",ValueInteger(val)); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_OBJECT: sprintf(work,"%d",(int)ValueObjectId(val)); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_FLOAT: sprintf(work,"%g",ValueFloat(val)); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_BOOL: sprintf(work,"%s",ValueBool(val) ? "TRUE" : "FALSE"); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_TIMESTAMP: sprintf(work,"%04d%02d%02d%02d%02d%02d", ValueDateTimeYear(val), ValueDateTimeMon(val) + 1, ValueDateTimeMDay(val), ValueDateTimeHour(val), ValueDateTimeMin(val), ValueDateTimeSec(val)); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_DATE: sprintf(work,"%04d%02d%02d", ValueDateTimeYear(val), ValueDateTimeMon(val) + 1, ValueDateTimeMDay(val)); LBS_EmitString(ValueStr(val),work); break; case GL_TYPE_TIME: sprintf(work,"%02d%02d%02d", ValueDateTimeHour(val), ValueDateTimeMin(val), ValueDateTimeSec(val)); LBS_EmitString(ValueStr(val),work); break; default: break; } LBS_EmitEnd(ValueStr(val)); ret = ValueStr(val); } LEAVE_FUNC; return (ret); }