Commit b3055b83 authored by Niels Möller's avatar Niels Möller
Browse files

* xalloc.c (lsh_object_clone): New function.

Rev: src/xalloc.c:1.15
Rev: src/xalloc.h:1.15
parent 3e611db0
......@@ -56,14 +56,15 @@ static void *debug_malloc(size_t real_size)
if (!res)
return NULL;
res += 2;
res[0] = count;
res[1] = real_size;
/* ((struct lsh_object *) (res + 2))->type = real_size; */
res[size+2] = ~count;
res[-2] = count;
res[-1] = real_size;
res[size] = ~count;
count++;
return (void *) (res + 2);
return (void *) res;
}
static void debug_free(void *m)
......@@ -121,6 +122,11 @@ struct lsh_string *lsh_string_alloc(UINT32 length)
void lsh_string_free(struct lsh_string *s)
{
if (!s)
return;
debug("lsh_string_free: freeing %p,\n", (void *) s);
#ifdef DEBUG_ALLOC
if (s->header.magic != -1717)
fatal("lsh_string_free: Not string!\n");
......@@ -139,6 +145,21 @@ struct lsh_object *lsh_object_alloc(struct lsh_class *class)
return instance;
}
struct lsh_object *lsh_object_clone(struct lsh_object *o)
{
struct lsh_object *i = xalloc(o->isa->size);
/* Copy header and all instance variables. Note that the header is
* now invalid, as the next pointer can't be copied directly. This
* is fixed by the gc_register call below. */
memcpy(i, o, o->isa->size);
i->alloc_method = LSH_ALLOC_HEAP;
gc_register(i);
return i;
}
struct list_header *lsh_list_alloc(struct lsh_class *class,
unsigned length, size_t element_size)
{
......@@ -163,8 +184,10 @@ void lsh_object_free(struct lsh_object *o)
if (o->alloc_method != LSH_ALLOC_HEAP)
fatal("lsh_object_free: Object not allocated on the heap!\n");
#if 0
if (o->isa->free_instance)
o->isa->free_instance(o);
#endif
lsh_free(o);
};
......@@ -202,7 +225,8 @@ struct lsh_object *lsh_object_check(struct lsh_class *class,
if (instance->dead)
fatal("lsh_object_check: Reference to dead object!\n");
if (instance->isa != class)
if ( (instance->alloc_method == LSH_ALLOC_HEAP)
&& (instance->isa != class))
fatal("lsh_object_check: Type error!\n");
return instance;
......@@ -222,11 +246,23 @@ struct lsh_object *lsh_object_check_subtype(struct lsh_class *class,
if (instance->dead)
fatal("lsh_object_check: Reference to dead object!\n");
/* Only heap allocated objects have a valid isa-pointer */
switch (instance->alloc_method)
{
case LSH_ALLOC_STATIC:
case LSH_ALLOC_STACK:
return instance;
case LSH_ALLOC_HEAP:
break;
default:
fatal("lsh_object_check_subtype: Memory corrupted!\n");
}
for (type = instance->isa; type; type=type->super_class)
if (type == class)
return instance;
fatal("lsh_object_check_subtype: Unexpected marked object!\n");
fatal("lsh_object_check_subtype: Type error!\n");
}
#endif /* DEBUG_ALLOC */
......
......@@ -51,6 +51,10 @@ void lsh_string_free(struct lsh_string *packet);
struct lsh_object *lsh_object_alloc(struct lsh_class *class);
void lsh_object_free(struct lsh_object *o);
/* NOTE: This won't work for if there are strings or other instance
* variables that can't be shared. */
struct lsh_object *lsh_object_clone(struct lsh_object *o);
void *lsh_space_alloc(size_t size);
void lsh_space_free(void *p);
......@@ -100,6 +104,12 @@ struct lsh_object *lsh_object_check_subtype(struct lsh_class *class,
struct class *(var) = (struct class *) lsh_object_alloc(&CLASS(class))
#define NEW_SPACE(x) ((x) = lsh_space_alloc(sizeof(*(x))))
#define CLONE(class, i) \
((struct class *) lsh_object_clone(CHECK_TYPE(class, (i))))
#define CLONED(class, var, i) \
struct class *(var) = CLONE(class, i)
#include "gc.h"
#define KILL(x) gc_kill((struct lsh_object *) (x))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment