You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
2.8 KiB
128 lines
2.8 KiB
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include "sol.h"
|
|
|
|
sol_object_t *_sol_gc_alloc_object(sol_state_t *state) {
|
|
sol_object_t *res = malloc(sizeof(sol_object_t));
|
|
if(!res) {
|
|
sol_set_error(state, state->OutOfMemory);
|
|
return sol_incref(state->None);
|
|
}
|
|
res->refcnt = 0;
|
|
res->ops = &(state->NullOps);
|
|
return sol_incref(res);
|
|
}
|
|
|
|
void _sol_gc_obj_free(sol_object_t *obj) {
|
|
if(!obj) {
|
|
printf("WARNING: Attempt to free NULL\n");
|
|
return;
|
|
}
|
|
if(sol_decref(obj) <= 0) {
|
|
if(obj->refcnt < 0) {
|
|
printf("WARNING: Encountered refcnt < 0!\nObject %p type %d ref %d\n", obj, obj->type, obj->refcnt);
|
|
} else {
|
|
sol_obj_release(obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
sol_object_t *sol_obj_acquire(sol_object_t *obj) {
|
|
return sol_incref(obj);
|
|
}
|
|
|
|
#ifdef DEBUG_GC
|
|
|
|
static FILE *gclog = NULL;
|
|
static int gcrefcnt = 0;
|
|
|
|
static char gctime[64];
|
|
|
|
/*
|
|
char *prtime() {
|
|
time_t t;
|
|
struct tm t2;
|
|
time(&t);
|
|
localtime_r(&t, &t2);
|
|
strftime(gctime, 64, "%Y/%m/%d %T", &t2);
|
|
return gctime;
|
|
}
|
|
*/
|
|
|
|
char *prtime() {return "";}
|
|
|
|
void sol_mm_initialize(sol_state_t *state) {
|
|
if(gclog) {
|
|
fprintf(gclog, " === Reopened at %s ===\n", prtime());
|
|
} else {
|
|
gclog = fopen("gclog.txt", "a");
|
|
fprintf(gclog, "=== Opened at %s ===\n", prtime());
|
|
}
|
|
gcrefcnt++;
|
|
}
|
|
|
|
void sol_mm_finalize(sol_state_t *state) {
|
|
gcrefcnt--;
|
|
fprintf(gclog, "=== Closed at %s ===\n", prtime());
|
|
if(gcrefcnt <= 0) {
|
|
fflush(gclog);
|
|
fclose(gclog);
|
|
gclog = NULL;
|
|
}
|
|
}
|
|
|
|
sol_object_t *_int_sol_alloc_object(const char *func, sol_state_t *state) {
|
|
fprintf(gclog, "%s\tA\n", func);
|
|
return _sol_gc_alloc_object(state);
|
|
}
|
|
|
|
sol_object_t *_int_sol_incref(const char *func, sol_object_t *obj) {
|
|
int oldref = obj->refcnt++;
|
|
fprintf(gclog, "%s\tI\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, oldref, obj->refcnt);
|
|
return obj;
|
|
}
|
|
|
|
void _int_sol_obj_free(const char *func, sol_object_t *obj) {
|
|
fprintf(gclog, "%s\tD\t%s\t%p\t%d\t->\t%d\n", func, obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
|
|
_sol_gc_obj_free(obj);
|
|
}
|
|
|
|
|
|
void sol_obj_release(sol_object_t *obj) {
|
|
fprintf(gclog, "\tF\t%s\t%p\n", obj->ops->tname, obj);
|
|
if(obj->ops->free) obj->ops->free(NULL, obj);
|
|
free(obj);
|
|
}
|
|
|
|
sol_object_t *_sol_gc_dsl_copier(sol_object_t *obj) {
|
|
fprintf(gclog, "<dsl>\tI\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, ++obj->refcnt);
|
|
return obj;
|
|
}
|
|
|
|
void _sol_gc_dsl_destructor(sol_object_t *obj) {
|
|
fprintf(gclog, "<dsl>\tD\t%s\t%p\t%d\t->\t%d\n", obj->ops->tname, obj, obj->refcnt, obj->refcnt - 1);
|
|
_sol_gc_obj_free(obj);
|
|
}
|
|
|
|
#else
|
|
|
|
sol_object_t *sol_alloc_object(sol_state_t *state) {
|
|
return _sol_gc_alloc_object(state);
|
|
}
|
|
|
|
void sol_obj_free(sol_object_t *obj) {
|
|
_sol_gc_obj_free(obj);
|
|
}
|
|
|
|
void sol_obj_release(sol_object_t *obj) {
|
|
if(obj->ops->free) {
|
|
obj->ops->free(NULL, obj);
|
|
}
|
|
free(obj);
|
|
}
|
|
|
|
void sol_mm_initialize(sol_state_t *state) {}
|
|
void sol_mm_finalize(sol_state_t *state) {}
|
|
|
|
#endif
|