faster startup - the end :-)

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

faster startup - the end :-)

Paolo Bonzini
Ok, we are done.  With this patch, we avoid doing useless work to fill
the primitive table, and the last 10% separating GNU Smalltalk from Ruby
(more or less) is covered.  I may give a try at removing the final
allInstancesDo: call upon quit, but that's faster quit (not faster
startup!).

Anyway, now hello world is 4-5 times faster than when I started.

Paolo

* looking for [hidden email]--2004b/smalltalk--devo--2.2--patch-227 to compare with
* comparing to [hidden email]--2004b/smalltalk--devo--2.2--patch-227
M  libgst/ChangeLog
M  libgst/genpr-parse.c
M  libgst/genpr-parse.h
M  libgst/interp.h
M  libgst/dict.c
M  libgst/save.c
M  libgst/dict.h
M  libgst/genpr-parse.y

* modified files

--- orig/libgst/ChangeLog
+++ mod/libgst/ChangeLog
@@ -1,5 +1,18 @@
 2006-12-28  Paolo Bonzini  <[hidden email]>
 
+ * libgst/dict.c: Change _gst_init_dictionary_on_image_load to be
+ whether the primitive table's checksum is ok.  If it is, just copy
+ the default primitive table just like in _gst_init_dictionary.
+ * libgst/dict.h: Adjust for above change.
+ * libgst/genpr-parse.y: Compute MD5 of DEF_FIL as checksum and
+ print it.
+ * libgst/interp.h: Declare _gst_primitives_md5.
+ * libgst/save.c: Save its contents, and compare it to pass the new flag
+ to _gst_init_dictionary_on_image_load.  Move checks from load_snapshot
+ to load_file_version.
+
+2006-12-28  Paolo Bonzini  <[hidden email]>
+
  * libgst/gstpriv.h: Remove F_FREE.
  * libgst/oop.c: Remove loops setting flags to F_FREE.  Set flags to 0
  instead of F_FREE elsewhere.


--- orig/libgst/dict.c
+++ mod/libgst/dict.c
@@ -1223,7 +1223,7 @@ create_class (const class_definition *ci
 
 
 mst_Boolean
-_gst_init_dictionary_on_image_load (size_t numOOPs)
+_gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches)
 {
   const class_definition *ci;
 
@@ -1259,7 +1259,12 @@ _gst_init_dictionary_on_image_load (size
 
   /* Important: this is called *after* _gst_init_symbols
      fills in _gst_vm_primitives_symbol! */
-  prepare_primitive_numbers_table ();
+  if (prim_table_matches)
+    memcpy (_gst_primitive_table, _gst_default_primitive_table,
+            sizeof (_gst_primitive_table));
+  else
+    prepare_primitive_numbers_table ();
+
   init_runtime_objects ();
   return (true);
 }


--- orig/libgst/dict.h
+++ mod/libgst/dict.h
@@ -603,10 +603,10 @@ extern void _gst_set_oop_bytes (OOP byte
 extern void _gst_free_cobject (OOP cObjOOP)
   ATTRIBUTE_HIDDEN;
 
-/* Loads the contents of the global variable from the Smalltalk
-   dictionary after NUMOOPS objects have been loaded from an
-   image.  */
-extern mst_Boolean _gst_init_dictionary_on_image_load (size_t numOOPs)
+/* Loads the contents of the global variables from the Smalltalk dictionary
+   after an image has been restored.  PRIM_TABLE_MATCHES if true if the
+   table of primitives is already set up correctly.  */
+extern mst_Boolean _gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches)
   ATTRIBUTE_HIDDEN;
 
 /* Transforms a primitive name into a primitive index, looking up


--- orig/libgst/genpr-parse.c
+++ mod/libgst/genpr-parse.c
@@ -89,6 +89,7 @@
 #line 52 "genpr-parse.y"
 
 #include "genprims.h"
+#include "md5.h"
 
 /* This program finds declarations of the form:
 
@@ -169,14 +170,14 @@ static string_list *current_ids;
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 117 "genpr-parse.y"
+#line 118 "genpr-parse.y"
 {
   Filament *fil;
   char *text;
   int id;
 }
 /* Line 193 of yacc.c.  */
-#line 180 "../../libgst/genpr-parse.c"
+#line 181 "../../libgst/genpr-parse.c"
  YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -189,7 +190,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 193 "../../libgst/genpr-parse.c"
+#line 194 "../../libgst/genpr-parse.c"
 
 #ifdef short
 # undef short
@@ -479,9 +480,9 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,   140,   140,   139,   148,   154,   153,   166,   171,   177,
-     182,   188,   196,   201,   210,   213,   220,   219,   232,   236,
-     241,   240
+       0,   141,   141,   140,   149,   155,   154,   167,   172,   178,
+     183,   189,   197,   202,   211,   214,   221,   220,   233,   237,
+     242,   241
 };
 #endif
 
@@ -1402,27 +1403,27 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 140 "genpr-parse.y"
+#line 141 "genpr-parse.y"
     {
     filprintf (stmt_fil, "#line %d \"prims.def\"\n{", yylineno);
   }
     break;
 
   case 3:
-#line 144 "genpr-parse.y"
+#line 145 "genpr-parse.y"
     {
     free_data ();
   }
     break;
 
   case 4:
-#line 148 "genpr-parse.y"
+#line 149 "genpr-parse.y"
     {
   }
     break;
 
   case 5:
-#line 154 "genpr-parse.y"
+#line 155 "genpr-parse.y"
     {
     current_id = 0;
     current_func_name = strdup ((yyvsp[(2) - (2)].text));
@@ -1432,13 +1433,13 @@ yyreduce:
     break;
 
   case 6:
-#line 161 "genpr-parse.y"
+#line 162 "genpr-parse.y"
     {
   }
     break;
 
   case 7:
-#line 167 "genpr-parse.y"
+#line 168 "genpr-parse.y"
     {
     gen_prim_id (current_func_name, (yyvsp[(1) - (2)].id), (yyvsp[(2) - (2)].text));
     free ((yyvsp[(2) - (2)].text));
@@ -1446,27 +1447,27 @@ yyreduce:
     break;
 
   case 8:
-#line 172 "genpr-parse.y"
+#line 173 "genpr-parse.y"
     {
   }
     break;
 
   case 9:
-#line 178 "genpr-parse.y"
+#line 179 "genpr-parse.y"
     {
     (yyval.id) = strtoul ((yyvsp[(2) - (2)].text), NULL, 10);
   }
     break;
 
   case 10:
-#line 182 "genpr-parse.y"
+#line 183 "genpr-parse.y"
     {
     (yyval.id) = current_id--;
   }
     break;
 
   case 11:
-#line 189 "genpr-parse.y"
+#line 190 "genpr-parse.y"
     {
     (yyval.text) = fildelete ((yyvsp[(2) - (3)].fil));
     strupr ((yyval.text));
@@ -1474,7 +1475,7 @@ yyreduce:
     break;
 
   case 12:
-#line 197 "genpr-parse.y"
+#line 198 "genpr-parse.y"
     {
     (yyval.fil) = filnew ("PRIM_", 5);
     filcat ((yyval.fil), (yyvsp[(1) - (1)].text));
@@ -1482,7 +1483,7 @@ yyreduce:
     break;
 
   case 13:
-#line 202 "genpr-parse.y"
+#line 203 "genpr-parse.y"
     {
     (yyval.fil) = (yyvsp[(1) - (3)].fil);
     filcat ((yyval.fil), " | PRIM_");
@@ -1491,26 +1492,26 @@ yyreduce:
     break;
 
   case 14:
-#line 211 "genpr-parse.y"
+#line 212 "genpr-parse.y"
     {
   }
     break;
 
   case 15:
-#line 214 "genpr-parse.y"
+#line 215 "genpr-parse.y"
     {
   }
     break;
 
   case 16:
-#line 220 "genpr-parse.y"
+#line 221 "genpr-parse.y"
     {
     (yyval.text) = strdup((yyvsp[(2) - (2)].text));
   }
     break;
 
   case 17:
-#line 224 "genpr-parse.y"
+#line 225 "genpr-parse.y"
     {
     gen_prim_id ((yyvsp[(3) - (5)].text), (yyvsp[(4) - (5)].id), (yyvsp[(5) - (5)].text));
     free ((yyvsp[(3) - (5)].text));
@@ -1519,14 +1520,14 @@ yyreduce:
     break;
 
   case 18:
-#line 233 "genpr-parse.y"
+#line 234 "genpr-parse.y"
     {
     filprintf (stmt_fil, "%d", (yyvsp[(2) - (2)].id));
   }
     break;
 
   case 20:
-#line 241 "genpr-parse.y"
+#line 242 "genpr-parse.y"
     {
     (yyval.id) = lookup_prim_id ((yyvsp[(3) - (3)].text));
     if ((yyval.id) == NOT_FOUND)
@@ -1535,7 +1536,7 @@ yyreduce:
     break;
 
   case 21:
-#line 247 "genpr-parse.y"
+#line 248 "genpr-parse.y"
     {
     (yyval.id) = (yyvsp[(4) - (5)].id);
     literal_fil = stmt_fil;
@@ -1544,7 +1545,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 1548 "../../libgst/genpr-parse.c"
+#line 1549 "../../libgst/genpr-parse.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1758,7 +1759,7 @@ yyreturn:
 }
 
 
-#line 253 "genpr-parse.y"
+#line 254 "genpr-parse.y"
 
 
 void
@@ -1865,12 +1866,16 @@ void
 output()
 {
   char *proto, *stmt, *def;
+  unsigned int md5[16 / sizeof (int)];
+
   gen_proto ("VMpr_HOLE");
 
   proto = fildelete (proto_fil);
   stmt = fildelete (stmt_fil);
   def = fildelete (def_fil);
 
+  md5_buffer (def, strlen (def), md5);
+
   printf ("%s\n"
   "%s\n"
   "intptr_t\n"
@@ -1884,6 +1889,8 @@ output()
   "  PRIM_FAILED;\n"
   "}\n"
   "\n"
+  "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
+  "\n"
   "void\n"
   "_gst_init_primitives()\n"
   "{\n"
@@ -1898,7 +1905,10 @@ output()
   "      _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
   "    }\n"
   "}\n"
-  "\n", proto, stmt, def, prim_no + 1);
+  "\n",
+  proto, stmt,
+  md5[0], md5[1], md5[2], md5[3],
+  def, prim_no + 1);
 
   free (proto);
   free (stmt);


--- orig/libgst/genpr-parse.h
+++ mod/libgst/genpr-parse.h
@@ -60,7 +60,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 117 "genpr-parse.y"
+#line 118 "genpr-parse.y"
 {
   Filament *fil;
   char *text;


--- orig/libgst/genpr-parse.y
+++ mod/libgst/genpr-parse.y
@@ -51,6 +51,7 @@
 
 %{
 #include "genprims.h"
+#include "md5.h"
 
 /* This program finds declarations of the form:
 
@@ -356,12 +357,16 @@ void
 output()
 {
   char *proto, *stmt, *def;
+  unsigned int md5[16 / sizeof (int)];
+
   gen_proto ("VMpr_HOLE");
 
   proto = fildelete (proto_fil);
   stmt = fildelete (stmt_fil);
   def = fildelete (def_fil);
 
+  md5_buffer (def, strlen (def), md5);
+
   printf ("%s\n"
   "%s\n"
   "intptr_t\n"
@@ -375,6 +380,8 @@ output()
   "  PRIM_FAILED;\n"
   "}\n"
   "\n"
+  "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
+  "\n"
   "void\n"
   "_gst_init_primitives()\n"
   "{\n"
@@ -389,7 +396,10 @@ output()
   "      _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
   "    }\n"
   "}\n"
-  "\n", proto, stmt, def, prim_no + 1);
+  "\n",
+  proto, stmt,
+  md5[0], md5[1], md5[2], md5[3],
+  def, prim_no + 1);
 
   free (proto);
   free (stmt);


--- orig/libgst/interp.h
+++ mod/libgst/interp.h
@@ -542,6 +542,11 @@ prim_table_entry;
 #define PRIM_RETURN_SMALL_INTEGER 0x0100 /* 31 or 63 bits */
 #define PRIM_RETURN_SMALL_SMALLINTEGER 0x0300 /* 30 or 62 bits */
 
+/* The checksum of the table of primitive numbers.  Right now it is an MD5,
+   computed from part of the C source code of prims.inl.  We compare it when
+   loading an image, to avoid having to reload the primitive table.  */
+extern int _gst_primitives_md5[4];
+
 /* The table of functions that implement the primitives.  */
 extern prim_table_entry _gst_primitive_table[NUM_PRIMITIVES];
 extern prim_table_entry _gst_default_primitive_table[NUM_PRIMITIVES];


--- orig/libgst/save.c
+++ mod/libgst/save.c
@@ -112,6 +112,7 @@ typedef struct save_file_header
   size_t space_grow_rate;
   size_t num_free_oops;
   intptr_t ot_base;
+  int prim_table_md5[4]; /* checksum for the primitive table */
 }
 save_file_header;
 
@@ -212,8 +213,8 @@ static void save_file_version (int image
 /* This function loads into HEADERP the header of the image file
    without checking its validity.
    This data is loaded from the IMAGEFD file descriptor.  */
-static void load_file_version (int imageFd,
-       save_file_header * headerp);
+static mst_Boolean load_file_version (int imageFd,
+      save_file_header * headerp);
 
 /* This function walks the OOP table and converts all the relative
    addresses for the instance variables to absolute ones.  */
@@ -423,6 +424,8 @@ save_file_version (int imageFd, struct s
   headerp->grow_threshold_percent = _gst_mem.grow_threshold_percent;
   headerp->space_grow_rate = _gst_mem.space_grow_rate;
   headerp->ot_base = (intptr_t) _gst_mem.ot_base;
+  memcpy (&headerp->prim_table_md5, _gst_primitives_md5, sizeof (_gst_primitives_md5));
+
   buffer_write (imageFd, headerp, sizeof (save_file_header));
 }
 
@@ -451,34 +454,11 @@ mst_Boolean
 load_snapshot (int imageFd)
 {
   save_file_header header;
+  int prim_table_matches;
 
   buffer_read_init (imageFd, READ_BUFFER_SIZE);
-  load_file_version (imageFd, &header);
-  if (strcmp (header.signature, SIGNATURE))
-    return (false);
-
-  /* different sizeof(PTR) not supported */
-  if (FLAG_CHANGED (header.flags, SLOT_SIZE_FLAG))
-    return (false);
-
-  if UNCOMMON ((wrong_endianness =
-         FLAG_CHANGED (header.flags, ENDIANNESS_FLAG)))
-    {
-      header.oopTableSize = BYTE_INVERT (header.oopTableSize);
-      header.edenSpaceSize = BYTE_INVERT (header.edenSpaceSize);
-      header.survSpaceSize = BYTE_INVERT (header.survSpaceSize);
-      header.oldSpaceSize = BYTE_INVERT (header.oldSpaceSize);
-      header.big_object_threshold = BYTE_INVERT (header.big_object_threshold);
-      header.grow_threshold_percent = BYTE_INVERT (header.grow_threshold_percent);
-      header.space_grow_rate = BYTE_INVERT (header.space_grow_rate);
-      header.version = BYTE_INVERT (header.version);
-      header.num_free_oops = BYTE_INVERT (header.num_free_oops);
-      header.ot_base = BYTE_INVERT (header.ot_base);
-    }
-
-  /* check for version mismatch; if so this image file is invalid */
-  if (header.version > VERSION_REQUIRED)
-    return (false);
+  if (!load_file_version (imageFd, &header))
+    return false;
 
 #ifdef SNAPSHOT_TRACE
   printf ("After loading header: %lld\n", file_pos + buf_pos);
@@ -510,7 +490,9 @@ load_snapshot (int imageFd)
   if (ot_delta)
     restore_all_pointer_slots ();
 
-  if (_gst_init_dictionary_on_image_load (num_used_oops))
+  prim_table_matches = !memcmp (header.prim_table_md5, _gst_primitives_md5,
+ sizeof (_gst_primitives_md5));
+  if (_gst_init_dictionary_on_image_load (prim_table_matches))
     {
 #ifdef SNAPSHOT_TRACE
       _gst_dump_oop_table ();
@@ -521,19 +503,47 @@ load_snapshot (int imageFd)
   return (false);
 }
 
-void
+mst_Boolean
 load_file_version (int imageFd,
    save_file_header * headerp)
 {
   buffer_read (imageFd, headerp, sizeof (save_file_header));
+  if (strcmp (headerp->signature, SIGNATURE))
+    return (false);
+
+  /* different sizeof(PTR) not supported */
+  if (FLAG_CHANGED (headerp->flags, SLOT_SIZE_FLAG))
+    return (false);
+
+  if UNCOMMON ((wrong_endianness =
+         FLAG_CHANGED (headerp->flags, ENDIANNESS_FLAG)))
+    {
+      headerp->oopTableSize = BYTE_INVERT (headerp->oopTableSize);
+      headerp->edenSpaceSize = BYTE_INVERT (headerp->edenSpaceSize);
+      headerp->survSpaceSize = BYTE_INVERT (headerp->survSpaceSize);
+      headerp->oldSpaceSize = BYTE_INVERT (headerp->oldSpaceSize);
+      headerp->big_object_threshold = BYTE_INVERT (headerp->big_object_threshold);
+      headerp->grow_threshold_percent = BYTE_INVERT (headerp->grow_threshold_percent);
+      headerp->space_grow_rate = BYTE_INVERT (headerp->space_grow_rate);
+      headerp->version = BYTE_INVERT (headerp->version);
+      headerp->num_free_oops = BYTE_INVERT (headerp->num_free_oops);
+      headerp->ot_base = BYTE_INVERT (headerp->ot_base);
+      headerp->prim_table_md5[0] = BYTE_INVERT (headerp->prim_table_md5[0]);
+      headerp->prim_table_md5[1] = BYTE_INVERT (headerp->prim_table_md5[1]);
+      headerp->prim_table_md5[2] = BYTE_INVERT (headerp->prim_table_md5[2]);
+      headerp->prim_table_md5[3] = BYTE_INVERT (headerp->prim_table_md5[3]);
+    }
+
+  /* check for version mismatch; if so this image file is invalid */
+  if (headerp->version > VERSION_REQUIRED)
+    return (false);
+
+  return (true);
 }
 
 void
 load_oop_table (int imageFd)
 {
-  OOP oop;
-  int i;
-
   /* Load in the valid OOP slots from previous dump.  The others are already
      initialized to free (0).  */
   buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);




_______________________________________________
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 - the end :-)

J Pfersich
Will all these changes be in 2.3.2 or 2.4?

At 07:09 PM 12/28/2006 +0100, Paolo Bonzini wrote:

>Ok, we are done.  With this patch, we avoid doing useless work to fill the
>primitive table, and the last 10% separating GNU Smalltalk from Ruby (more
>or less) is covered.  I may give a try at removing the final
>allInstancesDo: call upon quit, but that's faster quit (not faster startup!).
>
>Anyway, now hello world is 4-5 times faster than when I started.
>
>Paolo
>
>
>* looking for [hidden email]--2004b/smalltalk--devo--2.2--patch-227 to
>compare with
>* comparing to [hidden email]--2004b/smalltalk--devo--2.2--patch-227
>M  libgst/ChangeLog
>M  libgst/genpr-parse.c
>M  libgst/genpr-parse.h
>M  libgst/interp.h
>M  libgst/dict.c
>M  libgst/save.c
>M  libgst/dict.h
>M  libgst/genpr-parse.y
>
>* modified files
>
>--- orig/libgst/ChangeLog
>+++ mod/libgst/ChangeLog
>@@ -1,5 +1,18 @@
>  2006-12-28  Paolo Bonzini  <[hidden email]>
>
>+       * libgst/dict.c: Change _gst_init_dictionary_on_image_load to be
>+       whether the primitive table's checksum is ok.  If it is, just copy
>+       the default primitive table just like in _gst_init_dictionary.
>+       * libgst/dict.h: Adjust for above change.
>+       * libgst/genpr-parse.y: Compute MD5 of DEF_FIL as checksum and
>+       print it.
>+       * libgst/interp.h: Declare _gst_primitives_md5.
>+       * libgst/save.c: Save its contents, and compare it to pass the new
>flag
>+       to _gst_init_dictionary_on_image_load.  Move checks from load_snapshot
>+       to load_file_version.
>+
>+2006-12-28  Paolo Bonzini  <[hidden email]>
>+
>         * libgst/gstpriv.h: Remove F_FREE.
>         * libgst/oop.c: Remove loops setting flags to F_FREE.  Set flags to 0
>         instead of F_FREE elsewhere.
>
>
>--- orig/libgst/dict.c
>+++ mod/libgst/dict.c
>@@ -1223,7 +1223,7 @@ create_class (const class_definition *ci
>
>
>  mst_Boolean
>-_gst_init_dictionary_on_image_load (size_t numOOPs)
>+_gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches)
>  {
>    const class_definition *ci;
>
>@@ -1259,7 +1259,12 @@ _gst_init_dictionary_on_image_load (size
>
>    /* Important: this is called *after* _gst_init_symbols
>       fills in _gst_vm_primitives_symbol! */
>-  prepare_primitive_numbers_table ();
>+  if (prim_table_matches)
>+    memcpy (_gst_primitive_table, _gst_default_primitive_table,
>+            sizeof (_gst_primitive_table));
>+  else
>+    prepare_primitive_numbers_table ();
>+
>    init_runtime_objects ();
>    return (true);
>  }
>
>
>--- orig/libgst/dict.h
>+++ mod/libgst/dict.h
>@@ -603,10 +603,10 @@ extern void _gst_set_oop_bytes (OOP byte
>  extern void _gst_free_cobject (OOP cObjOOP)
>    ATTRIBUTE_HIDDEN;
>
>-/* Loads the contents of the global variable from the Smalltalk
>-   dictionary after NUMOOPS objects have been loaded from an
>-   image.  */
>-extern mst_Boolean _gst_init_dictionary_on_image_load (size_t numOOPs)
>+/* Loads the contents of the global variables from the Smalltalk dictionary
>+   after an image has been restored.  PRIM_TABLE_MATCHES if true if the
>+   table of primitives is already set up correctly.  */
>+extern mst_Boolean _gst_init_dictionary_on_image_load (mst_Boolean
>prim_table_matches)
>    ATTRIBUTE_HIDDEN;
>
>  /* Transforms a primitive name into a primitive index, looking up
>
>
>--- orig/libgst/genpr-parse.c
>+++ mod/libgst/genpr-parse.c
>@@ -89,6 +89,7 @@
>  #line 52 "genpr-parse.y"
>
>  #include "genprims.h"
>+#include "md5.h"
>
>  /* This program finds declarations of the form:
>
>@@ -169,14 +170,14 @@ static string_list *current_ids;
>
>  #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
>  typedef union YYSTYPE
>-#line 117 "genpr-parse.y"
>+#line 118 "genpr-parse.y"
>  {
>    Filament *fil;
>    char *text;
>    int id;
>  }
>  /* Line 193 of yacc.c.  */
>-#line 180 "../../libgst/genpr-parse.c"
>+#line 181 "../../libgst/genpr-parse.c"
>         YYSTYPE;
>  # define yystype YYSTYPE /* obsolescent; will be withdrawn */
>  # define YYSTYPE_IS_DECLARED 1
>@@ -189,7 +190,7 @@ typedef union YYSTYPE
>
>
>  /* Line 216 of yacc.c.  */
>-#line 193 "../../libgst/genpr-parse.c"
>+#line 194 "../../libgst/genpr-parse.c"
>
>  #ifdef short
>  # undef short
>@@ -479,9 +480,9 @@ static const yytype_int8 yyrhs[] =
>  /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
>  static const yytype_uint8 yyrline[] =
>  {
>-       0,   140,   140,   139,   148,   154,   153,   166,   171,   177,
>-     182,   188,   196,   201,   210,   213,   220,   219,   232,   236,
>-     241,   240
>+       0,   141,   141,   140,   149,   155,   154,   167,   172,   178,
>+     183,   189,   197,   202,   211,   214,   221,   220,   233,   237,
>+     242,   241
>  };
>  #endif
>
>@@ -1402,27 +1403,27 @@ yyreduce:
>    switch (yyn)
>      {
>          case 2:
>-#line 140 "genpr-parse.y"
>+#line 141 "genpr-parse.y"
>      {
>             filprintf (stmt_fil, "#line %d \"prims.def\"\n{", yylineno);
>           }
>      break;
>
>    case 3:
>-#line 144 "genpr-parse.y"
>+#line 145 "genpr-parse.y"
>      {
>             free_data ();
>           }
>      break;
>
>    case 4:
>-#line 148 "genpr-parse.y"
>+#line 149 "genpr-parse.y"
>      {
>           }
>      break;
>
>    case 5:
>-#line 154 "genpr-parse.y"
>+#line 155 "genpr-parse.y"
>      {
>             current_id = 0;
>             current_func_name = strdup ((yyvsp[(2) - (2)].text));
>@@ -1432,13 +1433,13 @@ yyreduce:
>      break;
>
>    case 6:
>-#line 161 "genpr-parse.y"
>+#line 162 "genpr-parse.y"
>      {
>           }
>      break;
>
>    case 7:
>-#line 167 "genpr-parse.y"
>+#line 168 "genpr-parse.y"
>      {
>             gen_prim_id (current_func_name, (yyvsp[(1) - (2)].id),
> (yyvsp[(2) - (2)].text));
>             free ((yyvsp[(2) - (2)].text));
>@@ -1446,27 +1447,27 @@ yyreduce:
>      break;
>
>    case 8:
>-#line 172 "genpr-parse.y"
>+#line 173 "genpr-parse.y"
>      {
>           }
>      break;
>
>    case 9:
>-#line 178 "genpr-parse.y"
>+#line 179 "genpr-parse.y"
>      {
>             (yyval.id) = strtoul ((yyvsp[(2) - (2)].text), NULL, 10);
>           }
>      break;
>
>    case 10:
>-#line 182 "genpr-parse.y"
>+#line 183 "genpr-parse.y"
>      {
>             (yyval.id) = current_id--;
>           }
>      break;
>
>    case 11:
>-#line 189 "genpr-parse.y"
>+#line 190 "genpr-parse.y"
>      {
>             (yyval.text) = fildelete ((yyvsp[(2) - (3)].fil));
>             strupr ((yyval.text));
>@@ -1474,7 +1475,7 @@ yyreduce:
>      break;
>
>    case 12:
>-#line 197 "genpr-parse.y"
>+#line 198 "genpr-parse.y"
>      {
>             (yyval.fil) = filnew ("PRIM_", 5);
>             filcat ((yyval.fil), (yyvsp[(1) - (1)].text));
>@@ -1482,7 +1483,7 @@ yyreduce:
>      break;
>
>    case 13:
>-#line 202 "genpr-parse.y"
>+#line 203 "genpr-parse.y"
>      {
>             (yyval.fil) = (yyvsp[(1) - (3)].fil);
>             filcat ((yyval.fil), " | PRIM_");
>@@ -1491,26 +1492,26 @@ yyreduce:
>      break;
>
>    case 14:
>-#line 211 "genpr-parse.y"
>+#line 212 "genpr-parse.y"
>      {
>           }
>      break;
>
>    case 15:
>-#line 214 "genpr-parse.y"
>+#line 215 "genpr-parse.y"
>      {
>           }
>      break;
>
>    case 16:
>-#line 220 "genpr-parse.y"
>+#line 221 "genpr-parse.y"
>      {
>             (yyval.text) = strdup((yyvsp[(2) - (2)].text));
>           }
>      break;
>
>    case 17:
>-#line 224 "genpr-parse.y"
>+#line 225 "genpr-parse.y"
>      {
>             gen_prim_id ((yyvsp[(3) - (5)].text), (yyvsp[(4) - (5)].id),
> (yyvsp[(5) - (5)].text));
>             free ((yyvsp[(3) - (5)].text));
>@@ -1519,14 +1520,14 @@ yyreduce:
>      break;
>
>    case 18:
>-#line 233 "genpr-parse.y"
>+#line 234 "genpr-parse.y"
>      {
>             filprintf (stmt_fil, "%d", (yyvsp[(2) - (2)].id));
>           }
>      break;
>
>    case 20:
>-#line 241 "genpr-parse.y"
>+#line 242 "genpr-parse.y"
>      {
>             (yyval.id) = lookup_prim_id ((yyvsp[(3) - (3)].text));
>             if ((yyval.id) == NOT_FOUND)
>@@ -1535,7 +1536,7 @@ yyreduce:
>      break;
>
>    case 21:
>-#line 247 "genpr-parse.y"
>+#line 248 "genpr-parse.y"
>      {
>             (yyval.id) = (yyvsp[(4) - (5)].id);
>             literal_fil = stmt_fil;
>@@ -1544,7 +1545,7 @@ yyreduce:
>
>
>  /* Line 1267 of yacc.c.  */
>-#line 1548 "../../libgst/genpr-parse.c"
>+#line 1549 "../../libgst/genpr-parse.c"
>        default: break;
>      }
>    YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
>@@ -1758,7 +1759,7 @@ yyreturn:
>  }
>
>
>-#line 253 "genpr-parse.y"
>+#line 254 "genpr-parse.y"
>
>
>  void
>@@ -1865,12 +1866,16 @@ void
>  output()
>  {
>    char *proto, *stmt, *def;
>+  unsigned int md5[16 / sizeof (int)];
>+
>    gen_proto ("VMpr_HOLE");
>
>    proto = fildelete (proto_fil);
>    stmt = fildelete (stmt_fil);
>    def = fildelete (def_fil);
>
>+  md5_buffer (def, strlen (def), md5);
>+
>    printf ("%s\n"
>           "%s\n"
>           "intptr_t\n"
>@@ -1884,6 +1889,8 @@ output()
>           "  PRIM_FAILED;\n"
>           "}\n"
>           "\n"
>+         "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
>+         "\n"
>           "void\n"
>           "_gst_init_primitives()\n"
>           "{\n"
>@@ -1898,7 +1905,10 @@ output()
>           "      _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
>           "    }\n"
>           "}\n"
>-         "\n", proto, stmt, def, prim_no + 1);
>+         "\n",
>+         proto, stmt,
>+         md5[0], md5[1], md5[2], md5[3],
>+         def, prim_no + 1);
>
>    free (proto);
>    free (stmt);
>
>
>--- orig/libgst/genpr-parse.h
>+++ mod/libgst/genpr-parse.h
>@@ -60,7 +60,7 @@
>
>  #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
>  typedef union YYSTYPE
>-#line 117 "genpr-parse.y"
>+#line 118 "genpr-parse.y"
>  {
>    Filament *fil;
>    char *text;
>
>
>--- orig/libgst/genpr-parse.y
>+++ mod/libgst/genpr-parse.y
>@@ -51,6 +51,7 @@
>
>  %{
>  #include "genprims.h"
>+#include "md5.h"
>
>  /* This program finds declarations of the form:
>
>@@ -356,12 +357,16 @@ void
>  output()
>  {
>    char *proto, *stmt, *def;
>+  unsigned int md5[16 / sizeof (int)];
>+
>    gen_proto ("VMpr_HOLE");
>
>    proto = fildelete (proto_fil);
>    stmt = fildelete (stmt_fil);
>    def = fildelete (def_fil);
>
>+  md5_buffer (def, strlen (def), md5);
>+
>    printf ("%s\n"
>           "%s\n"
>           "intptr_t\n"
>@@ -375,6 +380,8 @@ output()
>           "  PRIM_FAILED;\n"
>           "}\n"
>           "\n"
>+         "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
>+         "\n"
>           "void\n"
>           "_gst_init_primitives()\n"
>           "{\n"
>@@ -389,7 +396,10 @@ output()
>           "      _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
>           "    }\n"
>           "}\n"
>-         "\n", proto, stmt, def, prim_no + 1);
>+         "\n",
>+         proto, stmt,
>+         md5[0], md5[1], md5[2], md5[3],
>+         def, prim_no + 1);
>
>    free (proto);
>    free (stmt);
>
>
>--- orig/libgst/interp.h
>+++ mod/libgst/interp.h
>@@ -542,6 +542,11 @@ prim_table_entry;
>  #define PRIM_RETURN_SMALL_INTEGER      0x0100  /* 31 or 63 bits */
>  #define PRIM_RETURN_SMALL_SMALLINTEGER 0x0300  /* 30 or 62 bits */
>
>+/* The checksum of the table of primitive numbers.  Right now it is an MD5,
>+   computed from part of the C source code of prims.inl.  We compare it when
>+   loading an image, to avoid having to reload the primitive table.  */
>+extern int _gst_primitives_md5[4];
>+
>  /* The table of functions that implement the primitives.  */
>  extern prim_table_entry _gst_primitive_table[NUM_PRIMITIVES];
>  extern prim_table_entry _gst_default_primitive_table[NUM_PRIMITIVES];
>
>
>--- orig/libgst/save.c
>+++ mod/libgst/save.c
>@@ -112,6 +112,7 @@ typedef struct save_file_header
>    size_t space_grow_rate;
>    size_t num_free_oops;
>    intptr_t ot_base;
>+  int prim_table_md5[4]; /* checksum for the primitive table */
>  }
>  save_file_header;
>
>@@ -212,8 +213,8 @@ static void save_file_version (int image
>  /* This function loads into HEADERP the header of the image file
>     without checking its validity.
>     This data is loaded from the IMAGEFD file descriptor.  */
>-static void load_file_version (int imageFd,
>-                              save_file_header * headerp);
>+static mst_Boolean load_file_version (int imageFd,
>+                                     save_file_header * headerp);
>
>  /* This function walks the OOP table and converts all the relative
>     addresses for the instance variables to absolute ones.  */
>@@ -423,6 +424,8 @@ save_file_version (int imageFd, struct s
>    headerp->grow_threshold_percent = _gst_mem.grow_threshold_percent;
>    headerp->space_grow_rate = _gst_mem.space_grow_rate;
>    headerp->ot_base = (intptr_t) _gst_mem.ot_base;
>+  memcpy (&headerp->prim_table_md5, _gst_primitives_md5, sizeof
>(_gst_primitives_md5));
>+
>    buffer_write (imageFd, headerp, sizeof (save_file_header));
>  }
>
>@@ -451,34 +454,11 @@ mst_Boolean
>  load_snapshot (int imageFd)
>  {
>    save_file_header header;
>+  int prim_table_matches;
>
>    buffer_read_init (imageFd, READ_BUFFER_SIZE);
>-  load_file_version (imageFd, &header);
>-  if (strcmp (header.signature, SIGNATURE))
>-    return (false);
>-
>-  /* different sizeof(PTR) not supported */
>-  if (FLAG_CHANGED (header.flags, SLOT_SIZE_FLAG))
>-    return (false);
>-
>-  if UNCOMMON ((wrong_endianness =
>-         FLAG_CHANGED (header.flags, ENDIANNESS_FLAG)))
>-    {
>-      header.oopTableSize = BYTE_INVERT (header.oopTableSize);
>-      header.edenSpaceSize = BYTE_INVERT (header.edenSpaceSize);
>-      header.survSpaceSize = BYTE_INVERT (header.survSpaceSize);
>-      header.oldSpaceSize = BYTE_INVERT (header.oldSpaceSize);
>-      header.big_object_threshold = BYTE_INVERT
>(header.big_object_threshold);
>-      header.grow_threshold_percent = BYTE_INVERT
>(header.grow_threshold_percent);
>-      header.space_grow_rate = BYTE_INVERT (header.space_grow_rate);
>-      header.version = BYTE_INVERT (header.version);
>-      header.num_free_oops = BYTE_INVERT (header.num_free_oops);
>-      header.ot_base = BYTE_INVERT (header.ot_base);
>-    }
>-
>-  /* check for version mismatch; if so this image file is invalid */
>-  if (header.version > VERSION_REQUIRED)
>-    return (false);
>+  if (!load_file_version (imageFd, &header))
>+    return false;
>
>  #ifdef SNAPSHOT_TRACE
>    printf ("After loading header: %lld\n", file_pos + buf_pos);
>@@ -510,7 +490,9 @@ load_snapshot (int imageFd)
>    if (ot_delta)
>      restore_all_pointer_slots ();
>
>-  if (_gst_init_dictionary_on_image_load (num_used_oops))
>+  prim_table_matches = !memcmp (header.prim_table_md5, _gst_primitives_md5,
>+                               sizeof (_gst_primitives_md5));
>+  if (_gst_init_dictionary_on_image_load (prim_table_matches))
>      {
>  #ifdef SNAPSHOT_TRACE
>        _gst_dump_oop_table ();
>@@ -521,19 +503,47 @@ load_snapshot (int imageFd)
>    return (false);
>  }
>
>-void
>+mst_Boolean
>  load_file_version (int imageFd,
>                    save_file_header * headerp)
>  {
>    buffer_read (imageFd, headerp, sizeof (save_file_header));
>+  if (strcmp (headerp->signature, SIGNATURE))
>+    return (false);
>+
>+  /* different sizeof(PTR) not supported */
>+  if (FLAG_CHANGED (headerp->flags, SLOT_SIZE_FLAG))
>+    return (false);
>+
>+  if UNCOMMON ((wrong_endianness =
>+         FLAG_CHANGED (headerp->flags, ENDIANNESS_FLAG)))
>+    {
>+      headerp->oopTableSize = BYTE_INVERT (headerp->oopTableSize);
>+      headerp->edenSpaceSize = BYTE_INVERT (headerp->edenSpaceSize);
>+      headerp->survSpaceSize = BYTE_INVERT (headerp->survSpaceSize);
>+      headerp->oldSpaceSize = BYTE_INVERT (headerp->oldSpaceSize);
>+      headerp->big_object_threshold = BYTE_INVERT
>(headerp->big_object_threshold);
>+      headerp->grow_threshold_percent = BYTE_INVERT
>(headerp->grow_threshold_percent);
>+      headerp->space_grow_rate = BYTE_INVERT (headerp->space_grow_rate);
>+      headerp->version = BYTE_INVERT (headerp->version);
>+      headerp->num_free_oops = BYTE_INVERT (headerp->num_free_oops);
>+      headerp->ot_base = BYTE_INVERT (headerp->ot_base);
>+      headerp->prim_table_md5[0] = BYTE_INVERT (headerp->prim_table_md5[0]);
>+      headerp->prim_table_md5[1] = BYTE_INVERT (headerp->prim_table_md5[1]);
>+      headerp->prim_table_md5[2] = BYTE_INVERT (headerp->prim_table_md5[2]);
>+      headerp->prim_table_md5[3] = BYTE_INVERT (headerp->prim_table_md5[3]);
>+    }
>+
>+  /* check for version mismatch; if so this image file is invalid */
>+  if (headerp->version > VERSION_REQUIRED)
>+    return (false);
>+
>+  return (true);
>  }
>
>  void
>  load_oop_table (int imageFd)
>  {
>-  OOP oop;
>-  int i;
>-
>    /* Load in the valid OOP slots from previous dump.  The others are already
>       initialized to free (0).  */
>    buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);
>
>
>
>_______________________________________________
>help-smalltalk mailing list
>[hidden email]
>http://lists.gnu.org/mailman/listinfo/help-smalltalk



_______________________________________________
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 - the end :-)

Paolo Bonzini
J Pfersich wrote:
> Will all these changes be in 2.3.2 or 2.4?

2.4 (3.0?) :-)

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk