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"
  
  
  


Reply via email to