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 |
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 |
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 |
Free forum by Nabble | Edit this page |