示例#1
0
void
js_vm_mark (JSNode *n)
{
  unsigned int i;

  switch (n->type)
    {
    case JS_UNDEFINED:
    case JS_NULL:
    case JS_BOOLEAN:
    case JS_INTEGER:
    case JS_FLOAT:
    case JS_SYMBOL:
    case JS_NAN:
    case JS_IPTR:
    case JS_ARGS_FIX:
      /* Nothing here. */
      break;

    case JS_STRING:
      js_vm_mark_ptr (n->u.vstring);
      if (!n->u.vstring->staticp)
	js_vm_mark_ptr (n->u.vstring->data);

      js_vm_object_mark (n->u.vstring->prototype);
      break;

    case JS_OBJECT:
      js_vm_object_mark (n->u.vobject);
      break;

    case JS_ARRAY:
      if (js_vm_mark_ptr (n->u.varray))
	{
	  js_vm_mark_ptr (n->u.varray->data);

	  for (i = 0; i < n->u.varray->length; i++)
	    js_vm_mark (&n->u.varray->data[i]);

	  js_vm_object_mark (n->u.varray->prototype);
	}
      break;

    case JS_BUILTIN:
      if (js_vm_mark_ptr (n->u.vbuiltin))
	{
	  js_vm_mark_ptr (n->u.vbuiltin->info);

	  js_vm_object_mark (n->u.vbuiltin->info->prototype);
	  js_vm_object_mark (n->u.vbuiltin->prototype);

	  if (n->u.vbuiltin->info->mark_proc)
	    (*n->u.vbuiltin->info->mark_proc) (
					n->u.vbuiltin->info,
					n->u.vbuiltin->instance_context);
	}
      break;

    case JS_FUNC:
      js_vm_mark_ptr (n->u.vfunction);
      js_vm_mark_ptr (n->u.vfunction->implementation);
      js_vm_object_mark (n->u.vfunction->prototype);
      break;
    }
}
示例#2
0
void
js_vm_garbage_collect (JSVirtualMachine *vm, JSNode *fp, JSNode *sp)
{
  unsigned int i;
  unsigned long bytes_in_use;
  char buf[512];

  if (vm->verbose > 1)
    {
      sprintf_P (buf, heap_string_1, vm->num_consts, vm->num_globals,
	         JS_HOST_LINE_BREAK);
      //js_iostream_write (vm->s_stderr, buf, strlen (buf));
    }

  vm->gc.count++;

  /* Mark */

  /* Mark all constants. */
  for (i = 0; i < vm->num_consts; i++)
    js_vm_mark (&vm->consts[i]);

  /* Mark all globals. */
  for (i = 0; i < vm->num_globals; i++)
    js_vm_mark (&vm->globals[i]);

  /* Mark the buitin-infos of the core objects. */
  for (i = 0; i <= JS_IPTR; i++)
    js_vm_mark_ptr (vm->prim[i]);

  /* Mark stack. */

  /* STACKFRAME */

  /* Use brute force and mark the whole stack. */
  for (sp++; sp < vm->stack + vm->stack_size; sp++)
    {
      if (sp->type == JS_IPTR)
	{
	  /* Handle the stack frames here. */

	  /* Skip the return address. */
	  sp++;

	  /* Possible with-chain. */
	  if (sp->u.iptr)
	    {
	      JSUIntAlign *uip = sp->u.iptr;
	      JSUIntAlign ui = *uip;
	      JSNode *wp;

	      /* Mark the with-chain block. */
	      js_vm_mark_ptr (uip);

	      /* Mark the objects in the with-chain. */
	      wp = (JSNode *) ((unsigned char *) uip + sizeof (JSUIntAlign));

	      for (i = 0; i < ui; i++)
		js_vm_mark (&wp[i]);

	    }
	  sp++;

	  /* Skip the args_fix. */
	  sp++;

	  /*
	   * And now we point to the old_fp.  We skip it too at the
	   * for-loop.
	   */
	}
      else
	/* Mark this stack item. */
	js_vm_mark (sp);
    }

  /* Sweep all blocks and collect free nodes to the freelist. */

  /*bytes_in_use =*/ sweep (vm);

  if (vm->verbose > 1)
    {
      sprintf_P (buf, heap_string_2, bytes_in_use, vm->gc.bytes_free,
	       JS_HOST_LINE_BREAK);
      //js_iostream_write (vm->s_stderr, buf, strlen (buf));
    }
}
示例#3
0
void
js_vm_object_mark (JSObject *obj)
{
  int i;
  unsigned int num_objects;

  if (obj == NULL)
    return;

 tail_recursive:

  if (!js_vm_mark_ptr (obj))
    /* This object has already been marked.  Nothing to do here. */
    return;

  js_vm_mark_ptr (obj->props);

  /* Mark property hash. */
  if (obj->hash)
    {
      JSObjectPropHashBucket *b;
      int i;

      js_vm_mark_ptr (obj->hash);
      js_vm_mark_ptr (obj->hash_lengths);

      for (i = 0; i < HASH_SIZE; i++)
	for (b = obj->hash[i]; b; b = b->next)
	  {
	    js_vm_mark_ptr (b);
	    js_vm_mark_ptr (b->data);
	  }
    }

  /* Mark all non-object properties. */
  num_objects = 0;
  for (i = 0; i < obj->num_props; i++)
    {
      if (obj->props[i].value.type == JS_OBJECT)
	{
	  if (!js_vm_is_marked_ptr (obj->props[i].value.u.vobject))
	    num_objects++;
	}
      else
	js_vm_mark (&obj->props[i].value);
    }

  /* And finally, mark all objects we have left. */
  if (num_objects > 0)
    {
      /* Find the objects. */
      for (i = 0; i < obj->num_props; i++)
	if (obj->props[i].value.type == JS_OBJECT
	    && !js_vm_is_marked_ptr (obj->props[i].value.u.vobject))
	  {
	    if (num_objects == 1)
	      {
		/*
		 * Hahaa, this is the only non-marked object.  We can
		 * do a tail-recursion optimization.
		 */
		obj = obj->props[i].value.u.vobject;
		goto tail_recursive;
	      }

	    /* Just mark it. */
	    js_vm_mark (&obj->props[i].value);
	  }
    }
}