Example #1
0
static void hklr_gc_collectwhite(HklrObject* object)
{
  assert(object != NULL);

  if (object->color == HKL_COLOR_WHITE && !object->is_buffered)
  {
    object->color = HKL_COLOR_BLACK;

    switch (object->type)
    {
      // If the object is a hash table
      case HKL_TYPE_HASH:
        // Traverse the hash scanning every child
        hkl_hash_traverse(object->as.hash, hklr_gc_collectwhite_hash, NULL);
        break;

      // If the object is a reference
      case HKL_TYPE_REF:
        hklr_gc_collectwhite(object->as.object);
        break;

      default: break;
    }

    // queue up roots to free
    /* HKLR.gc_freed++;
    hklr_object_free(object);*/

    hkl_list_push_back(HKLR.gc_to_free, object);
  }
}
Example #2
0
static void hklr_gc_scan(HklrObject* object)
{
  if (object->color == HKL_COLOR_GRAY)
  {
    if (object->rc > 0)
    {
      hklr_gc_scanblack(object);
    }
    else
    {
      object->color = HKL_COLOR_WHITE;

      switch (object->type)
      {
        // If the object is a hash table
        case HKL_TYPE_HASH:
          // Traverse the hash scanning every child
          hkl_hash_traverse(object->as.hash, hklr_gc_scan_hash, NULL);
          break;

        // If the object is a reference
        case HKL_TYPE_REF:
          hklr_gc_scan(object->as.object);
          break;

        default: break;
      }
    }
  }
}
Example #3
0
static void hklr_gc_markgray(HklrObject* object)
{
  if (object->color != HKL_COLOR_GRAY)
  {
    object->color = HKL_COLOR_GRAY;

    switch (object->type)
    {
      // If the object is a hash table
      case HKL_TYPE_HASH:
        // Traverse the hash marking every child
        hkl_hash_traverse(object->as.hash, hklr_gc_markgray_hash, NULL);
        break;

      // If the object is a reference
      case HKL_TYPE_REF:

        object->as.object->rc--;
        hklr_gc_markgray(object->as.object);
        break;

      default: break;
    }
  }
}
Example #4
0
static void hklr_gc_release(HklrObject* object)
{
  switch (object->type)
  {
    // If the object is a hash table
    case HKL_TYPE_HASH:
      // Traverse the hash decrementing every child
      hkl_hash_traverse(object->as.hash, hklr_gc_dec_hash, NULL);
      break;

    // If the object is a reference
    case HKL_TYPE_REF:
      hklr_gc_dec(object->as.object);
      break; 

    default: break;
  }

  object->color = HKL_COLOR_BLACK;

  if (!object->is_buffered)
  {
    HKLR.gc_freed++;
    hklr_object_free(object);
  }
}
Example #5
0
void hklr_scope_pop()
{
  HklScope* scope = hkl_list_pop_back(HKLR.scopes);

  // decrement all the locals
  hkl_hash_traverse(scope->locals, hklr_gc_dec_hash, NULL);

  // dont dec upvals as they arent in our scope
  // hkl_hash_traverse(scope->upvals, hklr_gc_dec_hash, NULL);
  hkl_hash_free(scope->locals);
  hkl_hash_free(scope->upvals);

  hkl_free_object(scope);
}
Example #6
0
void hklr_shutdown()
{
  hklr_scope_pop();

  // free globals
  hkl_hash_traverse(HKLR.globals, hklr_gc_dec_hash, NULL);
  hkl_hash_free(HKLR.globals);

  // collect garbage
  hklr_gc_collect();

  hkl_list_free(HKLR.gc_to_free);

  hklr_object_free(HKLR.gc_roots);
  hklr_object_free(HKLR.gc_tail);
}
Example #7
0
void hklr_scope_pop()
{
  HklScope* scope = HKLR.scopes;

  HKLR.scopes = scope->prev;
  HKLR.scope_level--;

  // decrement all the locals
  hkl_hash_traverse(scope->locals, hklr_gc_dec_hash, NULL);

  // dont dec upvals as they arent in our scope
  // hkl_hash_traverse(scope->upvals, hklr_gc_dec_hash, NULL);
  hkl_hash_free(scope->locals);
  hkl_hash_free(scope->upvals);

  hkl_free_object(scope);
}
Example #8
0
static void hklr_gc_scanblack(HklrObject* object)
{
  object->color = HKL_COLOR_BLACK;

  switch (object->type)
  {
    // If the object is a hash table
    case HKL_TYPE_HASH:
      // Traverse the hash scanning every child
      hkl_hash_traverse(object->as.hash, hklr_gc_scanblack_hash, NULL);
      break;

    // If the object is a reference
    case HKL_TYPE_REF:
      hklr_gc_scanblack(object->as.object);
      break;

    default: break;
  }
}