Two more problems found in string.c; these relate to the creation of
temporary strings to hold results of transcoding, in string_concat and
string_compare.

As per the latest (I think) decision from Dan ("Avoiding the deadlands", 9th
April: http://www.mail-archive.com/perl6-internals@perl.org/msg09072.html),
the following patch does the following:

1) Add BUFFER_neonate_FLAG (actually renamed BUFFER_needs_GC_FLAG, since
this is not used at present, and can always be added again if it is needed
in the future) - feel free to change the name to anything you fancy
2) Add neonate counters to interpreter structure (I added three separate
counters; as it is really only required as a flag to indicate that cleanup
is needed, one would probably suffice)
3) Change GC routines to treat 'neonate' string/buffer headers in the same
way as constants
4) Change string_concat and string_compare to set and clear the 'neonate'
flag as required

Still required as per the above-referenced decision:
1) Implement equivalent flag for PMCs (unless the 'immune' flag serves the
same purpose?)
2) Procedure to clear neonate flag on all headers from time to time

Note that this patch gives compiler warnings in string.c because of the
'const' attribute on the parameters, and therefore should not be applied in
its current form; I'm sure somebody can figure out how best to resolve the
warnings.

--
Peter Gibbs
EmKel Systems

Index: include/parrot/interpreter.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v
retrieving revision 1.40
diff -u -r1.40 interpreter.h
--- include/parrot/interpreter.h 3 Apr 2002 04:01:41 -0000 1.40
+++ include/parrot/interpreter.h 22 Apr 2002 12:58:47 -0000
@@ -142,6 +142,9 @@
                                    requests are there? */
     UINTVAL GC_block_level;     /* How many outstanding GC block
                                    requests are there? */
+    UINTVAL neonate_strings;    /* How many protected newborn strings ? */
+    UINTVAL neonate_buffers;    /* How many protected newborn buffers ? */
+    UINTVAL neonate_PMCs;       /* How many protected newborn PMCs ? */
 } Interp;

 #define PCONST(i) PF_CONST(interpreter->code, (i))
Index: interpreter.c
===================================================================
RCS file: /home/perlcvs/parrot/interpreter.c,v
retrieving revision 1.84
diff -u -r1.84 interpreter.c
--- interpreter.c 15 Apr 2002 18:05:18 -0000  1.84
+++ interpreter.c 22 Apr 2002 13:05:56 -0000
@@ -497,6 +497,9 @@
     interpreter->memory_collected = 0;
     interpreter->DOD_block_level = 1;
     interpreter->GC_block_level = 1;
+    interpreter->neonate_strings = 0;
+    interpreter->neonate_buffers = 0;
+    interpreter->neonate_PMCs = 0;

     /* Set up the memory allocation system */
     mem_setup_allocator(interpreter);
Index: include/parrot/string.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/string.h,v
retrieving revision 1.35
diff -u -r1.35 string.h
--- include/parrot/string.h 24 Mar 2002 22:30:06 -0000  1.35
+++ include/parrot/string.h 22 Apr 2002 12:59:23 -0000
@@ -65,8 +65,8 @@
     /* Private flag for the GC system. Set if the buffer's in use as
      * far as the GC's concerned */
     BUFFER_live_FLAG = 1 << 12,
-    /* Mark the bufffer as needing GC */
-    BUFFER_needs_GC_FLAG = 1 << 13,
+    /* Mark the bufffer as newborn, for protection from infant death */
+    BUFFER_neonate_FLAG = 1 << 13,
     /* Mark the buffer as on the free list */
     BUFFER_on_free_list_FLAG = 1 << 14,
     /* This is a constant--don't kill it! */
Index: resources.c
===================================================================
RCS file: /home/perlcvs/parrot/resources.c,v
retrieving revision 1.45
diff -u -r1.45 resources.c
--- resources.c 19 Apr 2002 01:33:56 -0000  1.45
+++ resources.c 22 Apr 2002 13:00:47 -0000
@@ -341,7 +314,8 @@
     STRING *string_array = cur_string_arena->start_STRING;
     for (i = 0; i < cur_string_arena->used; i++) {
       /* Tentatively unused, unless it's a constant */
-      if (!(string_array[i].flags & BUFFER_constant_FLAG)) {
+      if (!(string_array[i].flags &
+            (BUFFER_constant_FLAG | BUFFER_neonate_FLAG))) {
         string_array[i].flags &= ~BUFFER_live_FLAG;
       }
     }
@@ -353,7 +327,8 @@
     Buffer *buffer_array = cur_buffer_arena->start_Buffer;
     for (i = 0; i < cur_buffer_arena->used; i++) {
       /* Tentatively unused, unless it's a constant */
-      if (!(buffer_array[i].flags & BUFFER_constant_FLAG)) {
+      if (!(buffer_array[i].flags &
+            (BUFFER_constant_FLAG | BUFFER_neonate_FLAG))) {
         buffer_array[i].flags &= ~BUFFER_live_FLAG;
       }
     }
Index: string.c
===================================================================
RCS file: /home/perlcvs/parrot/string.c,v
retrieving revision 1.73
diff -u -r1.73 string.c
--- string.c  15 Apr 2002 20:34:28 -0000  1.73
+++ string.c  22 Apr 2002 12:59:55 -0000
@@ -277,6 +277,8 @@
             if (a->type != b->type || a->encoding != b->encoding) {
                 b = string_transcode(interpreter, b, a->encoding, a->type,
                                      NULL);
+                interpreter->neonate_strings++;
+                b->flags |= BUFFER_neonate_FLAG;
             }
             result = string_make(interpreter, NULL, a->bufused +
b->bufused,
                                  a->encoding, 0, a->type);
@@ -285,6 +287,10 @@
                             b->bufstart, b->bufused);
             result->strlen = a->strlen + b->strlen;
             result->bufused = a->bufused + b->bufused;
+            if (b->flags & BUFFER_neonate_FLAG) {
+                b->flags &= ~BUFFER_neonate_FLAG;
+                interpreter->neonate_strings--;
+            }
         }
         else {
             return string_copy(interpreter, a);
@@ -576,8 +582,12 @@
     if (s1->type != s2->type || s1->encoding != s2->encoding) {
         s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
                               NULL);
+        interpreter->neonate_strings++;
+        s1->flags |= BUFFER_neonate_FLAG;
         s2 = string_transcode(interpreter, s2, NULL, string_unicode_type,
                               NULL);
+        interpreter->neonate_strings++;
+        s2->flags |= BUFFER_neonate_FLAG;
     }

     s1start = s1->bufstart;
@@ -599,6 +609,15 @@
         cmp = 1;
     if (cmp == 0 && s2start < s2end)
         cmp = -1;
+
+    if (s1->flags & BUFFER_neonate_FLAG) {
+        s1->flags &= ~BUFFER_neonate_FLAG;
+        interpreter->neonate_strings--;
+    }
+    if (s2->flags & BUFFER_neonate_FLAG) {
+        s2->flags &= ~BUFFER_neonate_FLAG;
+        interpreter->neonate_strings--;
+    }

     return cmp;
 }


Reply via email to