help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-smalltalk] faster startup - the end :-)


From: J Pfersich
Subject: Re: [Help-smalltalk] faster startup - the end :-)
Date: Fri, 29 Dec 2006 15:35:56 -0700

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 address@hidden/smalltalk--devo--2.2--patch-227 to compare with
* comparing to address@hidden/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  <address@hidden>

+       * 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  <address@hidden>
+
        * 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
address@hidden
http://lists.gnu.org/mailman/listinfo/help-smalltalk





reply via email to

[Prev in Thread] Current Thread [Next in Thread]