Exemplo n.º 1
0
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]);
    }
}
Exemplo n.º 2
0
/* Dump the header of the object with variables */
static void
_syx_memory_write_object_with_vars (SyxObject *object, FILE *image)
{
  syx_int32 data;

  _syx_memory_write ((SyxOop *)&object, FALSE, 1, image);
  _syx_memory_write (&object->klass, FALSE, 1, image);
  fputc (object->has_refs, image);
  fputc (object->is_constant, image);

  data = syx_object_vars_size ((SyxOop)object);
  data = SYX_COMPAT_SWAP_32(data);
  fwrite (&data, sizeof (syx_int32), 1, image);

  /* store instance variables, keep an eye on special cases */
  if ((SYX_OOP_EQ (object->klass, syx_block_context_class) ||
       SYX_OOP_EQ (object->klass, syx_method_context_class))
      && !SYX_IS_NIL (object->vars[SYX_VARS_CONTEXT_PART_STACK]))
    _syx_memory_write_vars_with_fp (object, SYX_VARS_CONTEXT_PART_STACK, SYX_VARS_CONTEXT_PART_FRAME_POINTER, image);
  else if (SYX_OOP_EQ (object->klass, syx_process_class)
           && !SYX_IS_NIL (object->vars[SYX_VARS_PROCESS_STACK]))
    _syx_memory_write_vars_with_fp (object, SYX_VARS_PROCESS_STACK, SYX_VARS_PROCESS_FRAME_POINTER, image);
  else
    _syx_memory_write (object->vars, TRUE, SYX_COMPAT_SWAP_32(data), image);
}
Exemplo n.º 3
0
/* Write the variables of a Process or of a Context, fixing the frame pointer to match a valid index
   in the stack */
static void
_syx_memory_write_vars_with_fp (SyxObject *object, SyxVariables stack_var, SyxVariables fp_var, FILE *image)
{
  SyxInterpFrame *frame = SYX_OOP_CAST_POINTER (object->vars[fp_var]);
  SyxOop stack;
  syx_int32 offset;

  if (!SYX_IS_NIL (frame->detached_frame))
    {
      stack = frame->detached_frame;
      offset = 0;
    }
  else
    {
      stack = object->vars[stack_var];
      offset = SYX_COMPAT_SWAP_32 (SYX_POINTERS_OFFSET (frame, SYX_OBJECT_DATA (stack)));
    }

  /* Write all variables before FRAME_POINTER */
  _syx_memory_write (object->vars, TRUE, fp_var, image);
  /* Now specify our own type for frame pointers */
  fputc (SYX_MEMORY_TYPE_FRAME_POINTER, image);
  /* We have to store the stack OOP in order to point to the right stack when loading back the image */
  _syx_memory_write (&stack, FALSE, 1, image);
  fwrite (&offset, sizeof (syx_int32), 1, image);
  /* Let's store the remaining variables */
  _syx_memory_write (object->vars + fp_var + 1, TRUE,
                     syx_object_vars_size ((SyxOop)object) - fp_var - 1, image);
}
Exemplo n.º 4
0
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]);
    }
}
Exemplo n.º 5
0
/*!
  Dumps all the memory.

  \param path the file path to put all inside
  \return FALSE if an error occurred
*/
syx_bool
syx_memory_save_image (syx_symbol path)
{
  SyxObject *object;
  FILE *image;
  syx_int32 data;

  if (!path)
    path = SYX_OBJECT_SYMBOL (syx_globals_at ("ImageFileName"));

  if (!path)
    return FALSE;

  image = fopen (path, "wb");
  if (!image)
    return FALSE;

  syx_memory_gc ();

  data = SYX_COMPAT_SWAP_32 (_syx_memory_size);
  fwrite (&data, sizeof (syx_int32), 1, image);
  data = SYX_COMPAT_SWAP_32 (_syx_freed_memory_top);
  fwrite (&data, sizeof (syx_int32), 1, image);
  _syx_memory_write (_syx_freed_memory, FALSE, _syx_freed_memory_top, image);

  _syx_scheduler_save (image);

  _syx_memory_write (&syx_globals, FALSE, 1, image);
  _syx_memory_write (&syx_symbols, FALSE, 1, image);

  for (object=syx_memory; object <= SYX_MEMORY_TOP; object++)
    {
      if (SYX_IS_NIL (object->klass))
        continue;

      _syx_memory_write ((SyxOop *)&object, FALSE, 1, image);
      _syx_memory_write (&object->klass, FALSE, 1, image);
      fputc (object->has_refs, image);
      fputc (object->is_constant, image);

      /* store instance variables */
      data = syx_object_vars_size ((SyxOop)object);
      data = SYX_COMPAT_SWAP_32(data);
      fwrite (&data, sizeof (syx_varsize), 1, image);
      _syx_memory_write (object->vars, TRUE, SYX_COMPAT_SWAP_32(data), image);

      /* store data */
      data = SYX_COMPAT_SWAP_32 (object->data_size);
      fwrite (&data, sizeof (syx_varsize), 1, image);
      if (object->data_size > 0)
        {
          if (object->has_refs)
            _syx_memory_write (object->data, TRUE, object->data_size, image);
          else
            {
#ifdef HAVE_LIBGMP
              if (SYX_OBJECT_IS_LARGE_INTEGER ((SyxOop)object))
                {
                  /* This algorithm is used to store large integers.
                     We need to specify how many bytes GMP wrote to the image,
                     for systems that doesn't support GMP */

                  syx_int32 offset = 0;
                  syx_nint start, end;
                  /* specify that's a large integer */
                  fputc (1, image);
                  /* make space to hold the offset */
                  fwrite (&offset, sizeof (syx_int32), 1, image);
                  start = ftell (image);
                  mpz_out_raw (image, SYX_OBJECT_LARGE_INTEGER ((SyxOop)object));
                  end = ftell (image);
                  offset = end - start;
                  /* go back to the offset */
                  fseek (image, - offset - sizeof (syx_int32), SEEK_CUR);
                  data = SYX_COMPAT_SWAP_32 (offset);
                  fwrite (&data, sizeof (syx_int32), 1, image);
                  /* return again to continue normal writing */
                  fseek (image, offset, SEEK_CUR);
                }
              else
#endif
                {
                  /* it's not a large integer */
                  fputc (0, image);
                  fwrite (object->data, sizeof (syx_int8), object->data_size, image);
                }
            }
        }
    }

  fclose (image);

  return TRUE;
}