/*! Returns a new SyxOop */ SyxOop syx_memory_alloc (void) { SyxOop oop; if (_syx_freed_memory_top == 0) { syx_memory_gc (); if (_syx_freed_memory_top == 0) syx_error ("object memory heap is really full\n"); } oop = _syx_freed_memory[--_syx_freed_memory_top]; /* Prevent the object from being collected */ if (_syx_memory_gc_trans_running) { if (_syx_memory_gc_trans_top == 0x100) syx_error ("transactions can hold up to 256 objects\n"); SYX_OBJECT_IS_MARKED(oop) = TRUE; _syx_memory_gc_trans[_syx_memory_gc_trans_top++] = oop; } else SYX_OBJECT_IS_MARKED(oop) = FALSE; return oop; }
INLINE void _syx_memory_gc_mark (SyxOop object) { syx_varsize i; if (!SYX_IS_OBJECT (object) || SYX_OBJECT_IS_MARKED(object) || SYX_IS_NIL(syx_object_get_class (object))) return; SYX_OBJECT_IS_MARKED(object) = TRUE; _syx_memory_gc_mark (SYX_OBJECT(object)->klass); /* Only the used stack part of the process must be marked */ if (SYX_OOP_EQ (syx_object_get_class (object), syx_process_class)) { SyxOop stack = SYX_PROCESS_STACK (object); SyxInterpFrame *frame = SYX_OOP_CAST_POINTER (SYX_PROCESS_FRAME_POINTER (object)); syx_int32 offset = SYX_POINTERS_OFFSET (frame->stack, SYX_OBJECT_DATA (stack)); SYX_OBJECT_IS_MARKED(stack) = TRUE; /* First mark variables except the process stack */ for (i=0; i < SYX_VARS_PROCESS_STACK; i++) _syx_memory_gc_mark (SYX_OBJECT_VARS(object)[i]); /* Mark detached frames */ while (frame) { _syx_memory_gc_mark (frame->detached_frame); frame = frame->parent_frame; } /* Now mark the stack */ for (i=0; i < offset; i++) _syx_memory_gc_mark (SYX_OBJECT_DATA(stack)[i]); /* Mark variables after the process stack */ for (i=SYX_VARS_PROCESS_STACK+1; i < syx_object_vars_size (object); i++) _syx_memory_gc_mark (SYX_OBJECT_VARS(object)[i]); /* Process has no data */ return; } else { for (i=0; i < syx_object_vars_size (object); i++) _syx_memory_gc_mark (SYX_OBJECT_VARS(object)[i]); } if (SYX_OBJECT_HAS_REFS (object)) { for (i=0; i < SYX_OBJECT_DATA_SIZE (object); i++) _syx_memory_gc_mark (SYX_OBJECT_DATA(object)[i]); } }
INLINE void _syx_memory_gc_mark (SyxOop object) { syx_varsize i; if (!SYX_IS_OBJECT (object) || SYX_OBJECT_IS_MARKED(object) || SYX_IS_NIL(syx_object_get_class (object))) return; SYX_OBJECT_IS_MARKED(object) = TRUE; _syx_memory_gc_mark (SYX_OBJECT(object)->klass); for (i=0; i < syx_object_vars_size (object); i++) _syx_memory_gc_mark (SYX_OBJECT_VARS(object)[i]); if (SYX_OBJECT_HAS_REFS (object)) { for (i=0; i < SYX_OBJECT_DATA_SIZE (object); i++) _syx_memory_gc_mark (SYX_OBJECT_DATA(object)[i]); } }
/*! Release a transaction started with syx_memory_gc_begin and unmark all objects in the transaction */ void syx_memory_gc_end (void) { syx_int32 i; if (--_syx_memory_gc_trans_running > 0) return; for (i=0; i < _syx_memory_gc_trans_top; i++) SYX_OBJECT_IS_MARKED(_syx_memory_gc_trans[i]) = FALSE; _syx_memory_gc_trans_top = 0; _syx_memory_gc_trans_running = 0; }