Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement REPR instance marking/freeing, so that slot mapping tables …
…won't go missing and anonymous types won't leak memory.
  • Loading branch information
jnthn committed Oct 2, 2010
1 parent df779fc commit bab7ae7
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/metamodel/rakudoobject.c
Expand Up @@ -31,6 +31,8 @@ void RakudoObject_initialize(PARROT_INTERP) {
/* Takes a representation and wraps it up in a REPR PMC. */
PMC * wrap_repr(PARROT_INTERP, void *REPR) {
PMC *repr_pmc = pmc_new_noinit(interp, repr_id);
PObj_custom_mark_SET(repr_pmc);
PObj_custom_destroy_SET(repr_pmc);
PMC_data(repr_pmc) = REPR;
return repr_pmc;
}
Expand Down
6 changes: 6 additions & 0 deletions src/metamodel/rakudoobject.h
Expand Up @@ -107,6 +107,12 @@ typedef struct {

/* This Parrot-specific addition to the API is used to free an object. */
void (*gc_free) (PARROT_INTERP, PMC *self, PMC *Object);

/* This Parrot-specific addition to the API is used to mark a REPR instance. */
void (*gc_mark_repr) (PARROT_INTERP, PMC *self);

/* This Parrot-specific addition to the API is used to free a REPR instance. */
void (*gc_free_repr) (PARROT_INTERP, PMC *self);
} REPRCommonalities;

/* Hint value to indicate the absence of an attribute lookup or method
Expand Down
2 changes: 2 additions & 0 deletions src/metamodel/reprs/KnowHOWREPR.c
Expand Up @@ -151,6 +151,8 @@ PMC * KnowHOWREPR_initialize(PARROT_INTERP) {
repr->get_str = get_str;
repr->gc_mark = gc_mark;
repr->gc_free = gc_free;
repr->gc_mark_repr = NULL;
repr->gc_free_repr = NULL;

/* Wrap it in a PMC. */
return wrap_repr(interp, repr);
Expand Down
2 changes: 2 additions & 0 deletions src/metamodel/reprs/P6int.c
Expand Up @@ -144,6 +144,8 @@ PMC * P6int_initialize(PARROT_INTERP) {
repr->get_str = get_str;
repr->gc_mark = gc_mark;
repr->gc_free = gc_free;
repr->gc_mark_repr = NULL;
repr->gc_free_repr = NULL;

/* Wrap it in a PMC. */
return wrap_repr(interp, repr);
Expand Down
2 changes: 2 additions & 0 deletions src/metamodel/reprs/P6num.c
Expand Up @@ -144,6 +144,8 @@ PMC * P6num_initialize(PARROT_INTERP) {
repr->get_str = get_str;
repr->gc_mark = gc_mark;
repr->gc_free = gc_free;
repr->gc_mark_repr = NULL;
repr->gc_free_repr = NULL;

/* Wrap it in a PMC. */
return wrap_repr(interp, repr);
Expand Down
15 changes: 15 additions & 0 deletions src/metamodel/reprs/P6opaque.c
Expand Up @@ -308,6 +308,19 @@ static void gc_free(PARROT_INTERP, PMC *self, PMC *obj) {
PMC_data(obj) = NULL;
}

/* This Parrot-specific addition to the API is used to mark a repr instance. */
static void gc_mark_repr(PARROT_INTERP, PMC *self) {
REPRP6opaque *repr = P6O_REPR_STRUCT(self);
if (!PMC_IS_NULL(repr->slot_mapping))
Parrot_gc_mark_PMC_alive(interp, repr->slot_mapping);
}

/* This Parrot-specific addition to the API is used to free a repr instance. */
static void gc_free_repr(PARROT_INTERP, PMC *self) {
mem_sys_free(PMC_data(self));
PMC_data(self) = NULL;
}

/* Sets up an instance of this representation with function pointers in place
* and no allocated slot storage. */
static PMC * repr_instance(PARROT_INTERP) {
Expand All @@ -332,6 +345,8 @@ static PMC * repr_instance(PARROT_INTERP) {
repr->common.get_str = get_str;
repr->common.gc_mark = gc_mark;
repr->common.gc_free = gc_free;
repr->common.gc_mark_repr = gc_mark_repr;
repr->common.gc_free_repr = gc_free_repr;
repr->slot_mapping = NULL;
repr->num_slots = 0;

Expand Down
2 changes: 2 additions & 0 deletions src/metamodel/reprs/P6str.c
Expand Up @@ -144,6 +144,8 @@ PMC * P6str_initialize(PARROT_INTERP) {
repr->get_str = get_str;
repr->gc_mark = gc_mark;
repr->gc_free = gc_free;
repr->gc_mark_repr = NULL;
repr->gc_free_repr = NULL;

/* Wrap it in a PMC. */
return wrap_repr(interp, repr);
Expand Down
14 changes: 13 additions & 1 deletion src/pmc/repr.pmc
@@ -1,8 +1,20 @@
#include "../metamodel/rakudoobject.h"

/* A representation is responsible for object layout. Representations
* all fill out a REPR struct and maybe have one of their own with some
* extra bits of information in it. This PMC is simply a wrapper around
* a REPR for the purposes of GC, etc. It's up to the REPR to set the
* PMC up as it wishes. */
pmclass REPR manual_attrs dynpmc group nqp {
/* XXX Needs custom mark/destroy implementing. */
VTABLE void mark() {
REPRCommonalities *repr = REPR_STRUCT(SELF);
if (repr->gc_mark_repr)
repr->gc_mark_repr(interp, SELF);
}

VTABLE void destroy() {
REPRCommonalities *repr = REPR_STRUCT(SELF);
if (repr->gc_free_repr)
repr->gc_free_repr(interp, SELF);
}
}

0 comments on commit bab7ae7

Please sign in to comment.