/*
** $Id: lgc.c,v 1.14 1997/12/17 20:48:58 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/


#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lua.h"



static int markobject (TObject *o);



/*
** =======================================================
** REF mechanism
** =======================================================
*/


int luaC_ref (TObject *o, int lock)
{
  int ref;
  if (ttype(o) == LUA_T_NIL)
    ref = -1;   /* special ref for nil */
  else {
    for (ref=0; ref<L->refSize; ref++)
      if (L->refArray[ref].status == FREE)
        goto found;
    /* no more empty spaces */ {
      int oldSize = L->refSize;
      L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref,
                                   refEM, MAX_WORD);
      for (ref=oldSize; ref<L->refSize; ref++)
        L->refArray[ref].status = FREE;
      ref = oldSize;
    } found:
    L->refArray[ref].o = *o;
    L->refArray[ref].status = lock ? LOCK : HOLD;
  }
  return ref;
}


void lua_unref (int ref)
{
  if (ref >= 0 && ref < L->refSize)
    L->refArray[ref].status = FREE;
}


TObject* luaC_getref (int ref)
{
  if (ref == -1)
    return &luaO_nilobject;
  if (ref >= 0 && ref < L->refSize &&
      (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
    return &L->refArray[ref].o;
  else
    return NULL;
}


static void travlock (void)
{
  int i;
  for (i=0; i<L->refSize; i++)
    if (L->refArray[i].status == LOCK)
      markobject(&L->refArray[i].o);
}


static int ismarked (TObject *o)
{
  /* valid only for locked objects */
  switch (o->ttype) {
    case LUA_T_STRING: case LUA_T_USERDATA:
      return o->value.ts->head.marked;
    case LUA_T_ARRAY:
      return o->value.a->head.marked;
    case LUA_T_CLOSURE:
      return o->value.cl->head.marked;
    case LUA_T_PROTO:
      return o->value.tf->head.marked;
#ifdef DEBUG
    case LUA_T_LINE: case LUA_T_CLMARK:
    case LUA_T_CMARK: case LUA_T_PMARK:
      lua_error("internal error");
#endif
    default:  /* nil, number or cproto */
      return 1;
  }
}


static void invalidaterefs (void)
{
  int i;
  for (i=0; i<L->refSize; i++)
    if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
      L->refArray[i].status = COLLECTED;
}



void luaC_hashcallIM (Hash *l)
{
  TObject t;
  ttype(&t) = LUA_T_ARRAY;
  for (; l; l=(Hash *)l->head.next) {
    avalue(&t) = l;
    luaD_gcIM(&t);
  }
}


void luaC_strcallIM (TaggedString *l)
{
  TObject o;
  ttype(&o) = LUA_T_USERDATA;
  for (; l; l=(TaggedString *)l->head.next)
    if (l->constindex == -1) {  /* is userdata? */
      tsvalue(&o) = l;
      luaD_gcIM(&o);
    }
}



static GCnode *listcollect (GCnode *l)
{
  GCnode *frees = NULL;
  while (l) {
    GCnode *next = l->next;
    l->marked = 0;
    while (next && !next->marked) {
      l->next = next->next;
      next->next = frees;
      frees = next;
      next = l->next;
    }
    l = next;
  }
  return frees;
}


static void strmark (TaggedString *s)
{
  if (!s->head.marked)
    s->head.marked = 1;
}


static void protomark (TProtoFunc *f)
{
  if (!f->head.marked) {
    LocVar *v = f->locvars;
    int i;
    f->head.marked = 1;
    if (f->fileName)
      strmark(f->fileName);
    for (i=0; i<f->nconsts; i++)
      markobject(&f->consts[i]);
    if (v) {
      for (; v->line != -1; v++)
        if (v->varname)
          strmark(v->varname);
    }
  }
}


static void closuremark (Closure *f)
{
  if (!f->head.marked) {
    int i;
    f->head.marked = 1;
    for (i=f->nelems; i>=0; i--)
      markobject(&f->consts[i]);
  }
}


static void hashmark (Hash *h)
{
  if (!h->head.marked) {
    int i;
    h->head.marked = 1;
    for (i=0; i<nhash(h); i++) {
      Node *n = node(h,i);
      if (ttype(ref(n)) != LUA_T_NIL) {
        markobject(&n->ref);
        markobject(&n->val);
      }
    }
  }
}


static void globalmark (void)
{
  TaggedString *g;
  for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
    if (g->u.globalval.ttype != LUA_T_NIL) {
      markobject(&g->u.globalval);
      strmark(g);  /* cannot collect non nil global variables */
    }
}


static int markobject (TObject *o)
{
  switch (ttype(o)) {
    case LUA_T_USERDATA:  case LUA_T_STRING:
      strmark(tsvalue(o));
      break;
    case LUA_T_ARRAY:
      hashmark(avalue(o));
      break;
    case LUA_T_CLOSURE:  case LUA_T_CLMARK:
      closuremark(o->value.cl);
      break;
    case LUA_T_PROTO: case LUA_T_PMARK:
      protomark(o->value.tf);
      break;
    default: break;  /* numbers, cprotos, etc */
  }
  return 0;
}



static void markall (void)
{
  luaD_travstack(markobject); /* mark stack objects */
  globalmark();  /* mark global variable values and names */
  travlock(); /* mark locked objects */
  luaT_travtagmethods(markobject);  /* mark fallbacks */
}


long lua_collectgarbage (long limit)
{
  unsigned long recovered = L->nblocks;  /* to subtract nblocks after gc */
  Hash *freetable;
  TaggedString *freestr;
  TProtoFunc *freefunc;
  Closure *freeclos;
  markall();
  invalidaterefs();
  freestr = luaS_collector();
  freetable = (Hash *)listcollect(&(L->roottable));
  freefunc = (TProtoFunc *)listcollect(&(L->rootproto));
  freeclos = (Closure *)listcollect(&(L->rootcl));
  L->GCthreshold *= 4;  /* to avoid GC during GC */
  luaC_hashcallIM(freetable);  /* GC tag methods for tables */
  luaC_strcallIM(freestr);  /* GC tag methods for userdata */
  luaD_gcIM(&luaO_nilobject);  /* GC tag method for nil (signal end of GC) */
  luaH_free(freetable);
  luaS_free(freestr);
  luaF_freeproto(freefunc);
  luaF_freeclosure(freeclos);
  recovered = recovered-L->nblocks;
  L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
  return recovered;
}


void luaC_checkGC (void)
{
  if (L->nblocks >= L->GCthreshold)
    lua_collectgarbage(0);
}

