Esempio n. 1
0
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::FreeAligned(void *blk)
{
	FLEXT_ASSERT(blk);

	char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *));
	size_t bytes = *(size_t *)((char *)blk-sizeof(size_t));

    if(UNLIKELY(bytes >= LARGEALLOC)) {
#if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_)
        sysmem_freeptr(ori);
#else
        // use C library function for large memory blocks
        free(ori);
#endif
    }
    else {
	//! We need system locking here for secondary threads!
        SYSLOCK();

#if defined(FLEXT_USE_CMEM)
	    free(ori);
#else
	    freebytes(ori,bytes);
#endif
        SYSUNLOCK();
    }
}
Esempio n. 2
0
FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::NewAligned(size_t bytes,int bitalign)
{
	const size_t ovh = sizeof(size_t)+sizeof(char *);
	const size_t alignovh = bitalign/8-1;
	bytes += ovh+alignovh;

    char *blk;
    if(UNLIKELY(bytes >= LARGEALLOC)) {
#if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_)
        blk = (char *)sysmem_newptr(bytes);
#else
        // use C library function for large memory blocks
        blk = (char *)malloc(bytes);
#endif
    }
    else {
	//! We need system locking here for secondary threads!
        SYSLOCK();

#if defined(FLEXT_USE_CMEM)
	    blk = (char *)malloc(bytes);
#else
	    blk = (char *)getbytes(bytes);
#endif
        SYSUNLOCK();
    }
	FLEXT_ASSERT(blk);

	char *ablk = reinterpret_cast<char *>((reinterpret_cast<size_t>(blk)+ovh+alignovh) & ~alignovh);
	*(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk;
	*(size_t *)(ablk-sizeof(size_t)) = bytes;
	return ablk;
}
Esempio n. 3
0
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::operator delete(void *blk)
{
    if(!blk) return;

    FLEXT_ASSERT(MemCheck(blk));

#ifdef FLEXT_DEBUGMEM
	char *ori = (char *)blk-sizeof(size_t)-sizeof(memtest);
#else
    char *ori = (char *)blk-sizeof(size_t);
#endif
	size_t bytes = *(size_t *)ori;

    if(UNLIKELY(bytes >= LARGEALLOC)) {
#if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_)
        sysmem_freeptr(ori);
#else
        // use C library function for large memory blocks
        free(ori);
#endif
    }
    else {
	    //! We need system locking here for secondary threads!
        SYSLOCK();
	    freebytes(ori,bytes);
        SYSUNLOCK();
    }
}
Esempio n. 4
0
FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::operator new(size_t bytes)
{
	bytes += sizeof(size_t);
#ifdef FLEXT_DEBUGMEM
    bytes += sizeof(memtest)*2;
#endif
    char *blk;
    if(UNLIKELY(bytes >= LARGEALLOC)) {
#if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_)
        blk = (char *)sysmem_newptr(bytes);
#else
        // use C library function for large memory blocks
        blk = (char *)malloc(bytes);
#endif
    }
    else {
    	//! We need system locking here for secondary threads!
        SYSLOCK();
	    blk = (char *)getbytes(bytes);
        SYSUNLOCK();
    }

	FLEXT_ASSERT(blk);

	*(size_t *)blk = bytes;
#ifdef FLEXT_DEBUGMEM
    *(size_t *)(blk+sizeof(size_t)) = memtest;
    *(size_t *)(blk+bytes-sizeof(memtest)) = memtest;
	return blk+sizeof(size_t)+sizeof(memtest);
#else
	return blk+sizeof(size_t);
#endif
}
Esempio n. 5
0
File: gc.c Progetto: roby85/Viper
//TODO: remove the stack and make a list of used/marked via header!! phead vs ptail
void gc_mark() {
    int i;
    PObject *obj;

    debug( "\n\n>>>>>>>MARK started %x\n", _phead);

    gc_trace();
    gc_keep_root();

    while (_phead) {
        obj = _phead;
        _phead = GCH_NEXT(obj);

        int tt = PTYPE(obj);
        switch (tt) {
            case PBYTEARRAY:
            case PSHORTARRAY:
                if (_PMS(obj)->seq)
                    GC_MARK( _PMS(obj)->seq);
                break;
            case PLIST:
            case PTUPLE: {
                i = PSEQUENCE_ELEMENTS(obj);
                PObject **objs = PSEQUENCE_OBJECTS(obj);
                if (objs) {
                    GC_KEEP_MANY(objs, i);
                    if (PSEQUENCE_BUFFER(obj)) {
                        GC_MARK(PSEQUENCE_BUFFER(obj));
                    }
                }
            }
            break;

            case PFSET:
            case PSET:
            case PDICT: {
                PDict *tmp = (PDict *)obj;
                int e = 0;
                HashEntry *ee;
                while ( (ee = phash_getentry(tmp, e++)) != NULL ) {
                    GC_KEEP_NOTNULL(ee->key);
                    if (tt == PDICT)
                        GC_KEEP_NOTNULL(ee->value);
                }
                if (tmp->entry)
                    GC_MARK(tmp->entry);
            }
            break;

            case PFUNCTION: {
                PFunction *tmp = (PFunction *)obj;
                if (tmp->defargs) GC_KEEP_MANY(tmp->storage, tmp->defargs);
                //TODO: the following can be optimized by avoiding the check on names...
                //and use macros to access function fields for portability...
                if (tmp->defkwargs) GC_KEEP_MANY(tmp->storage + tmp->defargs, 2 * tmp->defkwargs);
                if (PCODE_CELLVARS(PCODE_MAKE(tmp->codeobj))) {
                    obj = (PObject *)PFUNCTION_GET_CLOSURE(tmp);
                    GC_KEEP(obj);
                    //if (obj)
                    //   gc_keep_cells((PTuple *)obj);
                }
            }
            break;

            case PMETHOD: {
                PMethod *tmp = (PMethod *)obj;
                GC_KEEP(tmp->self);
                GC_KEEP(tmp->fn);
            }
            break;

            case PCLASS: {
                PClass *tmp = (PClass *)obj;
                GC_KEEP(tmp->bases);
                GC_KEEP(tmp->dict);
            }
            break;

            case PINSTANCE: {
                PInstance *tmp = (PInstance *)obj;
                GC_KEEP(tmp->base);
                GC_KEEP(tmp->dict);
            }
            break;

            case PITERATOR:
                GC_KEEP(   ((PIterator *)obj)->iterable );
                break;

            case PFRAME: {
                //debug("checking frame %i\n", obj);
                PFrame *tmp = (PFrame *)obj;
                PCode *code = PCODE_MAKE(tmp->code);
                GC_KEEP(tmp->parent);
                //GC_KEEP(tmp->block);
                GC_KEEP_MANY(PFRAME_PSTACK(tmp), tmp->sp);
                GC_KEEP_MANY(PFRAME_PLOCALS(tmp, code), code->nlocals);
                if (PCODE_HASVARS(code))
                    GC_KEEP_MANY(PFRAME_VARS(tmp, code), 2);

                /*if (PCODE_FREEVARS(code)) {
                    obj = PFRAME_TFREEVARS(tmp,code);//(PObject *)PFRAME_FREEVARS(tmp);
                    debug("keeping freevars %x for %x\n", obj, tmp);
                    GC_KEEP(obj);
                }
                debug("FRAME %x %i %i\n", tmp, PCODE_CELLVARS(code), PCODE_FREEVARS(code));
                if (PCODE_CELLVARS(code)) {
                    obj = (PObject *)PFRAME_CELLVARS(tmp);
                    debug("keeping cells for %x\n", obj);
                    GC_KEEP(obj);
                    //if (obj)
                    //    gc_keep_cells((PTuple *)obj);
                }
                */
            }
            break;
            /*case PBLOCK:
                //debug("checking block %i\n", obj);
                GC_KEEP(((PBlock *)obj)->next);
                break;
            */
            case PSYSOBJ: {
                PSysObject *tmp = (PSysObject *) obj;
                SYSLOCK();
                if (tmp->type == PSYS_TIMER) {
                    GC_KEEP(tmp->sys.timer.fn.fn);
                    GC_KEEP(tmp->sys.timer.fn.args);
                }
                SYSUNLOCK();
            }
            break;

            default:
                break;
        }
        //no need to mark obj. It has already been marked in gc_keep
        //GC_MARK(obj);
    }

    gc_trace();
    _phead = NULL;
    obj = PNT(_vm.thlist);
    do {
        PThread *pth = (PThread *)obj;
        debug( "Scanning thread %x %i for consts %x %i\n", pth, pth->header.flags, pth->cocache, pth->cachesize);
        for (i = 0; i < pth->cachesize; i++) {
            PObject *co = pth->cocache[i].obj;

            if (co && GCH_FLAG(co) != GC_USED)
                continue;
            //not marked, not staged, not null, not const_marked: remove it
            pth->cocache[i].obj = NULL;
        }
        obj = PNT(pth->next);
    } while (obj != PNT(_vm.thlist));
    debug( ">>>>>>>MARK stopped\n\n\n");

}
Esempio n. 6
0
File: gc.c Progetto: roby85/Viper
void gc_keep_root(void) {
    PObject *obj;
    int i;

    if (_vmpnt) {
        //get the root set
        obj = PNT(_vm.thlist);
        do {
            PThread *pth = (PThread *)obj;
            VThread vth = pth->th;
            debug( "Scanning thread %x %i\n", pth, pth->header.flags);
            if (vth && vosThGetStatus(vth) == VTHREAD_INACTIVE) {
                //terminated, remove from list...it will die if no references remain
                pth->prev->next = pth->next;
                pth->next->prev = pth->prev;
                GCH_FLAG_SET(pth, GC_USED);
                //free workspace
                //if PThread has references, it's ok. But it can't be restarted
                _gc_free(vth);
                pth->th = NULL;
            } else {
                GC_MARK(pth);
                if (pth->frame) GC_KEEP(pth->frame);
            }
            obj = PNT(pth->next);
        } while (obj != PNT(_vm.thlist));

        for (i = 0; i < _vm.nmodules; i++) {
            PModule *mod = VM_MODULE(i);
            GC_MARK(mod);
            if (PMODULE_IS_LOADED(mod)) {
                GC_KEEP_MANY(mod->globals, mod->nfo.nums.nglobals);
            } else {
                GC_KEEP(mod->nfo.frame);
            }
        }
        //-----> irqs could be modifing irq struct here: no worries
        SYSLOCK();
        //slots & irqstack
        for (i = 0; i < _vm.irqn; i++) {
            GC_KEEP(_vm.irqstack[i].fn);
            GC_KEEP_NOTNULL(_vm.irqstack[i].args);
        }

        for (i = 0; i < EXT_SLOTS; i++) {
            if (_vm.irqslots[0][i].fn) {
                GC_KEEP(_vm.irqslots[0][i].fn);
                GC_KEEP_NOTNULL(_vm.irqslots[0][i].args);
            }
            if (_vm.irqslots[1][i].fn) {
                GC_KEEP(_vm.irqslots[1][i].fn);
                GC_KEEP_NOTNULL(_vm.irqslots[1][i].args);
            }
        }
        if (_vm.irqcur) {
            GC_KEEP(_vm.irqcur->fn);
            GC_KEEP_NOTNULL(_vm.irqcur->args);
        }


        if (_vm.timers) {
            obj = _vm.timers;
            do {
                GC_KEEP(obj);
                obj = (PObject *)((PSysObject *)obj)->sys.timer.next;
            } while (obj != _vm.timers);
        }


        SYSUNLOCK();
        //-----> irq could be modifing irq struct here:
        //       - it can add something to irqslots: np, the objects added must be in an active frame (gc lock is on, no new frame can be created)
        //       - it can add something to irqstack from pin irq: np, the objects are sitting in irqslots
        //       - it can add something to irqstack from timers: that timer was in the timer list, so it is already kept
        //       - it can be the irqthread at 2 different times:
        //           - it modifies _vm.irqcur after putting it in a new frame: if happens up there, np. if happens now, already kept
        //           - it does _vm.irqn--: if happens up there, the removed irqfn is in irqcur. if happens here, already kept
    }

}