faster startup 10/n - why do we need F_FREE?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

faster startup 10/n - why do we need F_FREE?

Paolo Bonzini
This is cute.  We have plenty of flag bits to mark live objects, so we
don't need F_FREE!  This frees up a flag bit in the OOP data structures,
and avoids walking the free OOPs at startup (no matter if image loading
or starting from scratch) just to set that bit, saving 5-6%.

Paolo

* looking for [hidden email]--2004b/smalltalk--devo--2.2--patch-226 to compare with
* comparing to [hidden email]--2004b/smalltalk--devo--2.2--patch-226
M  libgst/gstpriv.h
M  libgst/oop.c
M  libgst/oop.h
M  libgst/print.c
M  libgst/save.c
M  libgst/oop.inl

* modified files

--- orig/libgst/gstpriv.h
+++ mod/libgst/gstpriv.h
@@ -258,9 +258,6 @@ enum {
      saves and loads.  */
   F_RUNTIME = 0xFF8000U,
 
-  /* Set if the OOP is currently unused.  */
-  F_FREE = 0x10U,
-
   /* Set if the references to the instance variables of the object
      are weak.  */
   F_WEAK = 0x20U,


--- orig/libgst/oop.c
+++ mod/libgst/oop.c
@@ -488,14 +488,16 @@ alloc_oop_table (size_t size)
 
   _gst_mem.num_free_oops = size;
 
+#if 0
   /* mark the OOPs as available */
   PREFETCH_START (_gst_mem.ot, PREF_WRITE | PREF_NTA);
   for (oop = _gst_mem.ot;
        oop < &_gst_mem.ot[_gst_mem.ot_size]; oop++)
     {
       PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
-      oop->flags = F_FREE;
+      oop->flags = 0;
     }
+#endif
 
   _gst_mem.first_allocated_oop = _gst_mem.ot;
   _gst_mem.last_allocated_oop = _gst_mem.last_swept_oop = _gst_mem.ot - 1;
@@ -520,14 +522,16 @@ _gst_realloc_oop_table (size_t newSize)
       return (false);
     }
 
+#if 0
   /* mark the new OOPs as available */
   PREFETCH_START (&_gst_mem.ot[_gst_mem.ot_size], PREF_WRITE | PREF_NTA);
   for (oop = &_gst_mem.ot[_gst_mem.ot_size];
        oop < &_gst_mem.ot[newSize]; oop++)
     {
       PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
-      oop->flags = F_FREE;
+      oop->flags = 0;
     }
+#endif
 
   _gst_mem.num_free_oops += newSize - _gst_mem.ot_size;
   _gst_mem.ot_size = newSize;
@@ -1438,7 +1442,7 @@ _gst_sweep_oop (OOP oop)
         _gst_mem_free (_gst_mem.old, oop->object);
     }
 
-  oop->flags = F_FREE;
+  oop->flags = 0;
 }
 
 void
@@ -1981,20 +1985,13 @@ _gst_copy_an_oop (OOP oop)
   printf ("Invalid size for OOP %p (%p)\n", oop, obj);
   abort ();
  }
-#endif
 
-      if UNCOMMON (oop->flags & F_FREE)
+      if UNCOMMON (oop->flags == 0)
  {
   printf ("Free OOP %p was referenced\n", oop);
-  /* If we're lucky, we can print some information on it...
-     if we're not, we segfault: not that bad given that
-     we'll abort pretty soon! */
-  oop->flags &= ~F_FREE;
-  _gst_display_oop (oop);
   abort ();
  }
 
-#if defined (GC_DEBUGGING)
       if UNCOMMON ((oop->flags & F_OLD) ||
   IS_SURVIVOR_ADDR(obj, _gst_mem.active_half == &_gst_mem.surv[1]))
         {


--- orig/libgst/oop.h
+++ mod/libgst/oop.h
@@ -220,7 +220,7 @@ struct memory_space
   /* The OOP flag corresponding to the active survivor space */
   int active_flag;
 
-  /* The OOP flag corresponding to the inactive survivor space, plus F_FREE */
+  /* The OOP flag corresponding to the inactive survivor space.  */
   int live_flags;
 
   /* These hold onto the object incubator's state */


--- orig/libgst/oop.inl
+++ mod/libgst/oop.inl
@@ -106,7 +106,7 @@ static inline OOP alloc_oop (PTR obj, in
   ((oop)->flags & F_REACHABLE)
 
 #define IS_OOP_FREE(oop) \
-  ((oop)->flags & F_FREE)
+  ((oop)->flags == 0)
 
 /* Checks to see if INDEX (a long index into the OOP table, 1 based
    due to being called from Smalltalk via a primitive) represents a


--- orig/libgst/print.c
+++ mod/libgst/print.c
@@ -320,7 +320,7 @@ _gst_classify_addr (void *addr)
 void
 _gst_display_oop_short (OOP oop)
 {
-  if (oop->flags & F_FREE)
+  if (IS_OOP_FREE (oop))
     printf ("%-10p   Free\n", oop);
   else
     {
@@ -351,7 +351,7 @@ _gst_display_oop (OOP oop)
       return;
     }
 
-  if (oop->flags & F_FREE)
+  if (IS_OOP_FREE (oop))
     printf ("%-10p   Free\n", oop);
   else
     {


--- orig/libgst/save.c
+++ mod/libgst/save.c
@@ -355,7 +355,7 @@ make_oop_table_to_be_saved (struct save_
  }
       else
  {
-  myOOPTable[i].flags = F_FREE;
+  myOOPTable[i].flags = 0;
   header->num_free_oops++;
  }
     }
@@ -535,7 +535,7 @@ load_oop_table (int imageFd)
   int i;
 
   /* Load in the valid OOP slots from previous dump.  The others are already
-     initialized to F_FREE.  */
+     initialized to free (0).  */
   buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);
   if UNCOMMON (wrong_endianness)
     fixup_byte_order (_gst_mem.ot,
@@ -564,8 +564,7 @@ load_normal_oops (int imageFd)
 
       PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
       flags = oop->flags;
-
-      if (flags & F_FREE)
+      if (IS_OOP_FREE (oop))
  continue;
 
       /* FIXME: a small amount of garbage is saved that is produced
@@ -598,7 +597,7 @@ load_normal_oops (int imageFd)
           buffer_read (imageFd, object, size);
           if UNCOMMON (wrong_endianness)
     fixup_byte_order (object,
-      (oop->flags & F_BYTE)
+      (flags & F_BYTE)
       ? OBJ_HEADER_SIZE_WORDS
       : size / sizeof (PTR));
 
@@ -609,9 +608,7 @@ load_normal_oops (int imageFd)
     abort ();
         }
 
-      /* Remove flags that are invalid after an image has been loaded.  */
       oop->object = object;
-
       if (flags & F_WEAK)
  _gst_make_oop_weak (oop);
     }



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: faster startup 10/n - why do we need F_FREE?

kaveman
CONTENTS DELETED
The author has deleted this message.