cvsuser 02/12/30 02:46:56
Modified: . dod.c headers.c smallobject.c
include/parrot dod.h headers.h pobj.h
t/pmc nci.t
Log:
mark5 - PMC/Buffer unification #10
Revision Changes Path
1.40 +70 -73 parrot/dod.c
Index: dod.c
===================================================================
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -w -r1.39 -r1.40
--- dod.c 27 Dec 2002 09:33:11 -0000 1.39
+++ dod.c 30 Dec 2002 10:46:53 -0000 1.40
@@ -1,7 +1,7 @@
/* dod.c
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: dod.c,v 1.39 2002/12/27 09:33:11 leo Exp $
+ * $Id: dod.c,v 1.40 2002/12/30 10:46:53 leo Exp $
* Overview:
* Handles dead object destruction of the various headers
* Data Structure and Algorithms:
@@ -39,12 +39,14 @@
/* if object is a PMC and contains buffers or PMCs, then attach
* the PMC to the chained mark list
*/
- if (PObj_is_PMC_TEST(obj) &&
- ((PObj_get_FLAGS(obj) & mask) || ((PMC*)obj)->metadata)) {
+ if (PObj_is_PMC_TEST(obj)) {
+ if ( (PObj_get_FLAGS(obj) & mask) || ((PMC*)obj)->metadata) {
/* put it on the end of the list */
interpreter->mark_ptr->next_for_GC = (PMC *)obj;
- /* Explicitly make the tail of the linked list be self-referential */
+ /* Explicitly make the tail of the linked list be
+ * self-referential */
interpreter->mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj;
+ }
return;
}
#if ! DISABLE_GC_DEBUG
@@ -230,39 +232,6 @@
}
}
-/* Free up any PMCs that aren't in use */
-void
-free_unused_PMCs(struct Parrot_Interp *interpreter)
-{
- struct Small_Object_Arena *cur_arena;
- UINTVAL i, total_used = 0;
- struct Small_Object_Pool *pool = interpreter->arena_base->pmc_pool;
-
- /* Run through all the buffer header pools and mark */
- for (cur_arena = pool->last_Arena;
- NULL != cur_arena; cur_arena = cur_arena->prev) {
- PMC *pmc_array = cur_arena->start_objects;
-
- for (i = 0; i < cur_arena->used; i++) {
- /* If it's not live or on the free list, put it on the free list.
- * Note that it is technically possible to have a PMC be both
- * on_free_list and live, because of our conservative stack-walk
- * collection. We must be wary of this case. */
-
- /* live_FLAG | on_free_list_FLAG | constant_FLAG */
- if (!PObj_is_live_or_free_TESTALL(&pmc_array[i])) {
- pool->add_free_object(interpreter, pool, &pmc_array[i]);
- }
- else if (!PObj_on_free_list_TEST(&pmc_array[i])) {
- total_used++;
- PObj_live_CLEAR(&pmc_array[i]);
- }
- }
- }
- interpreter->active_PMCs += total_used;
- pool->num_free_objects = pool->total_objects - total_used;
-}
-
#ifdef GC_IS_MALLOC
/* clear ref count */
@@ -287,7 +256,7 @@
/* clear COWed external FLAG */
PObj_external_CLEAR(b);
/* the real external flag */
- if (!PObj_bufstart_external_TEST(b))
+ if (PObj_bufstart_external_TEST(b))
PObj_external_SET(b);
/* if cleanup (Parrot_destroy) constants are dead too */
PObj_constant_CLEAR(b);
@@ -337,22 +306,18 @@
}
#endif /* GC_IS_MALLOC */
-/* Put any buffers that are now unused, on to the free list.
+/* Put any buffers/PMCs that are now unused, on to the pools free list.
* If GC_IS_MALLOC bufstart gets freed too if possible.
* Avoid buffers that are immune from collection (ie, constant) */
void
-free_unused_buffers(struct Parrot_Interp *interpreter,
- struct Small_Object_Pool *pool, int cleanup)
+free_unused_pobjects(struct Parrot_Interp *interpreter,
+ struct Small_Object_Pool *pool)
{
struct Small_Object_Arena *cur_arena;
UINTVAL i, total_used = 0;
UINTVAL object_size = pool->object_size;
+ UINTVAL wash_size = object_size - sizeof(Buffer);
-#ifdef GC_IS_MALLOC
- if (!cleanup) {
- used_cow(interpreter, pool, 0);
- }
-#endif /* GC_IS_MALLOC */
/* Run through all the buffer header pools and mark */
for (cur_arena = pool->last_Arena;
NULL != cur_arena; cur_arena = cur_arena->prev) {
@@ -364,39 +329,61 @@
* on_free_list and live, because of our conservative stack-walk
* collection. We must be wary of this case. */
if (!PObj_is_live_or_free_TESTALL(b)) {
-#ifndef GC_IS_MALLOC
- if (pool->mem_pool) {
+#if GC_VERBOSE
+ if (GC_DEBUG(interpreter) && PObj_report_TEST(b))
+ fprintf(stderr, "Freeing pobject %p -> %p\n",
+ b, b->bufstart);
+#endif
+ /* if object is a PMC and needs destroying */
+ if (PObj_is_PMC_TEST(b)) {
+ /* then destroy it here, add_free_pmc is called from
+ * more_objects too
+ */
+ if (PObj_active_destroy_TEST(b))
+ ((PMC *)b)->vtable->destroy(interpreter, (PMC *)b);
+ }
+ else {
+ /* else object is a buffer(like) */
+#ifdef GC_IS_MALLOC
+ /* free allocated space at bufstart,
+ * but not if it is used COW or external
+ */
+ if (b->bufstart && !PObj_is_external_or_free_TESTALL(b)) {
+ if (PObj_is_string_TEST(b)) {
+ int *refcount = ((int *)b->bufstart);
+
+ if (!--(*refcount))
+ free(refcount); /* the actual bufstart */
+ }
+ else
+ free(b->bufstart);
+ }
+#else
if (!PObj_COW_TEST(b)) {
((struct Memory_Pool *)
- pool->mem_pool)->guaranteed_reclaimable +=
- b->buflen;
+ pool->mem_pool)->guaranteed_reclaimable += b->buflen;
}
((struct Memory_Pool *)
pool->mem_pool)->possibly_reclaimable += b->buflen;
- }
#endif
- /* clean memory for buffer_likes, no need to clean
- * strings - a slight optimization would be to have
- * a separate flag for buffer_likes
+ /*
+ * clean memory for buffer_likes
+ * this is the slow thing in the whole sub, so PMCs
+ * have there own add_free function, which clears
+ * PMC specific data members
*/
- if (!PObj_is_string_TEST(b) &&
- object_size > sizeof(Buffer))
- memset(b + 1, 0, object_size - sizeof(Buffer));
- add_free_buffer(interpreter, pool, b);
+ memset(b + 1, 0, wash_size);
+ }
+ pool->add_free_object(interpreter, pool, b);
}
else if (!PObj_on_free_list_TEST(b)) {
+ /* should be live then */
total_used++;
- }
PObj_live_CLEAR(b);
- b = (Buffer *)((char *)b + object_size);
}
+ b = (Buffer *)((char *)b + object_size);
}
-#ifdef GC_IS_MALLOC
- if (!cleanup) {
- clear_cow(interpreter, pool, 0);
}
-#endif /* GC_IS_MALLOC */
- interpreter->active_Buffers += total_used;
pool->num_free_objects = pool->total_objects - total_used;
}
@@ -508,7 +495,6 @@
}
Parrot_block_DOD(interpreter);
- interpreter->active_PMCs = 0;
interpreter->active_Buffers = 0;
/* Now go trace the PMCs */
@@ -518,13 +504,24 @@
trace_active_buffers(interpreter);
/* Now put unused PMCs on the free list */
- free_unused_PMCs(interpreter);
+ header_pool = interpreter->arena_base->pmc_pool;
+ free_unused_pobjects(interpreter, header_pool);
+ interpreter->active_PMCs =
+ header_pool->total_objects - header_pool->num_free_objects;
/* And unused buffers on the free list */
for (j = 0; j < (INTVAL)interpreter->arena_base->num_sized; j++) {
header_pool = interpreter->arena_base->sized_header_pools[j];
if (header_pool) {
- free_unused_buffers(interpreter, header_pool, 0);
+#ifdef GC_IS_MALLOC
+ used_cow(interpreter, header_pool, 0);
+#endif
+ free_unused_pobjects(interpreter, header_pool);
+ interpreter->active_Buffers +=
+ header_pool->total_objects - header_pool->num_free_objects;
+#ifdef GC_IS_MALLOC
+ clear_cow(interpreter, header_pool, 0);
+#endif
}
}
#ifdef GC_IS_MALLOC
1.27 +11 -43 parrot/headers.c
Index: headers.c
===================================================================
RCS file: /cvs/public/parrot/headers.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -w -r1.26 -r1.27
--- headers.c 27 Dec 2002 09:33:11 -0000 1.26
+++ headers.c 30 Dec 2002 10:46:53 -0000 1.27
@@ -1,7 +1,7 @@
/* headers.c
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: headers.c,v 1.26 2002/12/27 09:33:11 leo Exp $
+ * $Id: headers.c,v 1.27 2002/12/30 10:46:53 leo Exp $
* Overview:
* Header management functions. Handles getting of various headers,
* and pool creation
@@ -34,13 +34,12 @@
add_free_pmc(struct Parrot_Interp *interpreter,
struct Small_Object_Pool *pool, void *pmc)
{
- if (PObj_active_destroy_TEST((PMC *)pmc))
- ((PMC *)pmc)->vtable->destroy(interpreter, (PMC *)pmc);
PObj_flags_SETTO((PMC *)pmc, PObj_on_free_list_FLAG);
/* Don't let it point to garbage memory */
((PMC *)pmc)->data = NULL;
((PMC *)pmc)->metadata = NULL;
+ ((PMC *)pmc)->synchronize = NULL;
/* Copied from add_free_object */
*(void **)pmc = pool->free_list;
@@ -60,6 +59,10 @@
pool->free_list = *(void **)pmc;
PObj_flags_SETTO(pmc, PObj_is_PMC_FLAG);
+ /* PMCs mem is already washed, set pointers to NULL if needed */
+ SET_NULL(pmc->data);
+ SET_NULL(pmc->metadata);
+ SET_NULL(pmc->synchronize);
return pmc;
}
@@ -75,41 +78,6 @@
/** Buffer Header Functions for small-object lookup table **/
-void
-add_free_buffer(struct Parrot_Interp *interpreter,
- struct Small_Object_Pool *pool, void *vp_buffer)
-{
- Buffer *buffer = (Buffer *)vp_buffer;
-
- if (GC_DEBUG(interpreter) && PObj_report_TEST(buffer))
- fprintf(stderr, "Freeing buffer %p -> %p\n", buffer, buffer->bufstart);
-
-#ifdef GC_IS_MALLOC
- /* free allocated space at bufstart, but not if it is used
- * COW or it is external
- */
- /* external_FLAG | on_free_list_FLAG */
- if (buffer->bufstart && !PObj_is_external_or_free_TESTALL(buffer))
- {
- if (PObj_is_string_TEST(buffer)) {
- int *refcount = ((int *)buffer->bufstart);
-
- if (!--(*refcount))
- free(refcount); /* the actual bufstart */
- }
- else
- free(buffer->bufstart);
- }
-#endif /* GC_IS_MALLOC */
- PObj_flags_SETTO(buffer, PObj_on_free_list_FLAG);
- /* Use the right length */
- buffer->buflen = 0;
-
- /* Copied from add_free_object */
- *(void **)buffer = pool->free_list;
- pool->free_list = buffer;
-}
-
void *
get_free_buffer(struct Parrot_Interp *interpreter,
struct Small_Object_Pool *pool)
@@ -124,6 +92,7 @@
/* Don't let it point to garbage memory */
buffer->bufstart = NULL;
+ buffer->buflen = 0;
/* Clear the flagpole (especially _on_free_list_FLAG) */
PObj_flags_CLEARALL(buffer);
#if ! DISABLE_GC_DEBUG
@@ -156,7 +125,7 @@
pmc_pool->get_free_object = get_free_pmc;
pmc_pool->alloc_objects = alloc_pmcs;
pmc_pool->more_objects = more_traceable_objects;
- pmc_pool->mem_pool = interpreter->arena_base->memory_pool;
+ pmc_pool->mem_pool = NULL;
return pmc_pool;
}
@@ -174,7 +143,6 @@
struct Small_Object_Pool *pool =
new_small_object_pool(interpreter, buffer_size, num_headers);
- pool->add_free_object = add_free_buffer;
pool->get_free_object = get_free_buffer;
pool->alloc_objects = alloc_buffers;
pool->more_objects = more_traceable_objects;
@@ -265,7 +233,7 @@
arena_base->constant_string_header_pool :
interpreter->arena_base->string_header_pool);
PObj_flags_SETTO(string, flags | PObj_is_string_FLAG);
- string->strstart = 0;
+ SET_NULL(string->strstart);
return string;
}
@@ -437,7 +405,7 @@
if (pool) {
if (j == -1) {
if (i == 2)
- free_unused_PMCs(interpreter);
+ free_unused_pobjects(interpreter, pool);
}
else {
#ifdef GC_IS_MALLOC
@@ -447,7 +415,7 @@
used_cow(interpreter, pool, 1);
else
#endif
- free_unused_buffers(interpreter, pool, 1);
+ free_unused_pobjects(interpreter, pool);
}
}
if (i == 2 && pool) {
1.18 +3 -2 parrot/smallobject.c
Index: smallobject.c
===================================================================
RCS file: /cvs/public/parrot/smallobject.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -w -r1.17 -r1.18
--- smallobject.c 27 Dec 2002 09:33:12 -0000 1.17
+++ smallobject.c 30 Dec 2002 10:46:53 -0000 1.18
@@ -1,7 +1,7 @@
/* resources.c
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: smallobject.c,v 1.17 2002/12/27 09:33:12 leo Exp $
+ * $Id: smallobject.c,v 1.18 2002/12/30 10:46:53 leo Exp $
* Overview:
* Handles the accessing of small object pools (header pools)
* Data Structure and Algorithms:
@@ -63,7 +63,8 @@
add_free_object(struct Parrot_Interp *interpreter,
struct Small_Object_Pool *pool, void *to_add)
{
- /* This code is copied to add_free_pmc and add_free_buffer */
+ /* This code is copied to add_free_pmc */
+ PObj_flags_SETTO((PObj *)to_add, PObj_on_free_list_FLAG);
*(void **)to_add = pool->free_list;
pool->free_list = to_add;
}
1.9 +4 -4 parrot/include/parrot/dod.h
Index: dod.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/dod.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -r1.8 -r1.9
--- dod.h 27 Dec 2002 09:33:37 -0000 1.8
+++ dod.h 30 Dec 2002 10:46:55 -0000 1.9
@@ -1,7 +1,7 @@
/* dod.h
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: dod.h,v 1.8 2002/12/27 09:33:37 leo Exp $
+ * $Id: dod.h,v 1.9 2002/12/30 10:46:55 leo Exp $
* Overview:
* Handles dead object destruction of the various headers
* Data Structure and Algorithms:
@@ -44,9 +44,9 @@
void trace_system_areas(struct Parrot_Interp *);
void trace_mem_block(struct Parrot_Interp *, size_t, size_t);
-void free_unused_buffers(struct Parrot_Interp *interpreter,
- struct Small_Object_Pool *pool, int cleanup);
-void free_unused_PMCs(struct Parrot_Interp *interpreter);
+void free_unused_pobjects(struct Parrot_Interp *interpreter,
+ struct Small_Object_Pool *pool);
+
void used_cow(struct Parrot_Interp *interpreter,
struct Small_Object_Pool *pool, int cleanup);
void clear_cow(struct Parrot_Interp *interpreter,
1.13 +1 -3 parrot/include/parrot/headers.h
Index: headers.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/headers.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -w -r1.12 -r1.13
--- headers.h 21 Dec 2002 10:07:38 -0000 1.12
+++ headers.h 30 Dec 2002 10:46:55 -0000 1.13
@@ -1,7 +1,7 @@
/* headers.h
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: headers.h,v 1.12 2002/12/21 10:07:38 leo Exp $
+ * $Id: headers.h,v 1.13 2002/12/30 10:46:55 leo Exp $
* Overview:
* Header management functions. Handles getting of various headers,
* and pool creation
@@ -31,8 +31,6 @@
struct Small_Object_Pool *pool);
/* buffer header small-object methods */
-void add_free_buffer(struct Parrot_Interp *interpreter,
- struct Small_Object_Pool *pool, void *buffer);
void *get_free_buffer(struct Parrot_Interp *interpreter,
struct Small_Object_Pool *pool);
void alloc_buffers(struct Parrot_Interp *interpreter,
1.10 +2 -1 parrot/include/parrot/pobj.h
Index: pobj.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/pobj.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -r1.9 -r1.10
--- pobj.h 27 Dec 2002 09:33:37 -0000 1.9
+++ pobj.h 30 Dec 2002 10:46:55 -0000 1.10
@@ -1,7 +1,7 @@
/* pobj.h
* Copyright: (When this is determined...it will go here)
* CVS Info
- * $Id: pobj.h,v 1.9 2002/12/27 09:33:37 leo Exp $
+ * $Id: pobj.h,v 1.10 2002/12/30 10:46:55 leo Exp $
* Overview:
* Parrot Object data members and flags enum
* Data Structure and Algorithms:
@@ -198,6 +198,7 @@
#define PObj_external_SET(o) PObj_flag_SET(external, o)
#define PObj_external_CLEAR(o) PObj_flag_CLEAR(external, o)
+#define PObj_bufstart_external_TEST(o) PObj_flag_TEST(bufstart_external, o)
#define PObj_bufstart_external_SET(o) PObj_flag_SET(bufstart_external, o)
#define PObj_report_TEST(o) PObj_flag_TEST(report, o)
1.6 +2 -2 parrot/t/pmc/nci.t
Index: nci.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/nci.t,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -r1.5 -r1.6
--- nci.t 15 Dec 2002 07:05:46 -0000 1.5
+++ nci.t 30 Dec 2002 10:46:56 -0000 1.6
@@ -185,7 +185,7 @@
set I0, 1 # prototype used - unchecked
set I1, 0 # items on stack - unchecked
new P5, .PerlString
- set P5, "ko\n"
+ set P5, "ko\n" # big HACK, broken with GC_IS_MALLOC
invoke
ne I5, 2, nok_1
ne I0, 0, nok_2 # test return value convention
@@ -216,7 +216,7 @@
set I0, 1 # prototype used - unchecked
set I1, 0 # items on stack - unchecked
new P5, .PerlString
- set P5, "ko\n"
+ set P5, "ko\n" # big HACK, broken with GC_IS_MALLOC
invoke # cant test ret value yet, print it
dlfunc P0, P1, "nci_ip", "ip"
print "dlfunced\n"