Mercurial > hg > xemacs-beta
comparison src/dumper.c @ 5118:e0db3c197671 ben-lisp-object
merge up to latest default branch, doesn't compile yet
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 21:18:49 -0600 |
parents | 1a14c304cb8e |
children | 19a72041c5ed |
comparison
equal
deleted
inserted
replaced
5117:3742ea8250b5 | 5118:e0db3c197671 |
---|---|
235 int count; | 235 int count; |
236 } pdump_reloc_table; | 236 } pdump_reloc_table; |
237 | 237 |
238 static Rawbyte *pdump_rt_list = 0; | 238 static Rawbyte *pdump_rt_list = 0; |
239 | 239 |
240 #ifndef MC_ALLOC | 240 #ifndef NEW_GC |
241 void | 241 void |
242 pdump_objects_unmark (void) | 242 pdump_objects_unmark (void) |
243 { | 243 { |
244 int i; | 244 int i; |
245 Rawbyte *p = pdump_rt_list; | 245 Rawbyte *p = pdump_rt_list; |
259 } | 259 } |
260 } else | 260 } else |
261 break; | 261 break; |
262 } | 262 } |
263 } | 263 } |
264 #endif /* not MC_ALLOC */ | 264 #endif /* not NEW_GC */ |
265 | 265 |
266 | 266 |
267 #ifdef MC_ALLOC | 267 #ifdef NEW_GC |
268 /* The structure of the dump file looks like this: | 268 /* The structure of the dump file looks like this: |
269 0 - header | 269 0 - header |
270 - dumped objects | 270 - dumped objects |
271 stab_offset - mc allocation table (count, size, address) for individual | 271 stab_offset - mc allocation table (count, size, address) for individual |
272 allocation and relocation at load time. | 272 allocation and relocation at load time. |
279 - nb_root_blocks*struct(void *, size, info) for global | 279 - nb_root_blocks*struct(void *, size, info) for global |
280 objects to restore | 280 objects to restore |
281 - root lisp object address/value couples with the count | 281 - root lisp object address/value couples with the count |
282 preceding the list | 282 preceding the list |
283 */ | 283 */ |
284 #else /* not MC_ALLOC */ | 284 #else /* not NEW_GC */ |
285 /* The structure of the dump file looks like this: | 285 /* The structure of the dump file looks like this: |
286 0 - header | 286 0 - header |
287 - dumped objects | 287 - dumped objects |
288 stab_offset - nb_cv_data*struct(dest, adr) for in-object externally | 288 stab_offset - nb_cv_data*struct(dest, adr) for in-object externally |
289 represented data | 289 represented data |
294 data-segment blocks to restore | 294 data-segment blocks to restore |
295 - relocation table | 295 - relocation table |
296 - root lisp object address/value couples with the count | 296 - root lisp object address/value couples with the count |
297 preceding the list | 297 preceding the list |
298 */ | 298 */ |
299 #endif /* not MC_ALLOC */ | 299 #endif /* not NEW_GC */ |
300 | 300 |
301 | 301 |
302 #define PDUMP_SIGNATURE "XEmacsDP" | 302 #define PDUMP_SIGNATURE "XEmacsDP" |
303 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1) | 303 #define PDUMP_SIGNATURE_LEN (sizeof (PDUMP_SIGNATURE) - 1) |
304 | 304 |
432 static Bytecount max_size; | 432 static Bytecount max_size; |
433 static int pdump_fd; | 433 static int pdump_fd; |
434 static void *pdump_buf; | 434 static void *pdump_buf; |
435 static FILE *pdump_out; | 435 static FILE *pdump_out; |
436 | 436 |
437 #ifdef MC_ALLOC | 437 #ifdef NEW_GC |
438 /* PDUMP_HASHSIZE is a large prime. */ | 438 /* PDUMP_HASHSIZE is a large prime. */ |
439 #define PDUMP_HASHSIZE 1000003 | 439 #define PDUMP_HASHSIZE 1000003 |
440 /* Nothing special about PDUMP_HASH_MULTIPLIER: arbitrary odd integer | 440 /* Nothing special about PDUMP_HASH_MULTIPLIER: arbitrary odd integer |
441 smaller than PDUMP_HASHSIZE. */ | 441 smaller than PDUMP_HASHSIZE. */ |
442 #define PDUMP_HASH_MULTIPLIER 12347 | 442 #define PDUMP_HASH_MULTIPLIER 12347 |
443 /* Nothing special about PDUMP_HASH_STEP: arbitrary integer for linear | 443 /* Nothing special about PDUMP_HASH_STEP: arbitrary integer for linear |
444 probing. */ | 444 probing. */ |
445 #define PDUMP_HASH_STEP 574853 | 445 #define PDUMP_HASH_STEP 574853 |
446 #else /* not MC_ALLOC */ | 446 #else /* not NEW_GC */ |
447 #define PDUMP_HASHSIZE 200001 | 447 #define PDUMP_HASHSIZE 200001 |
448 #endif /* not MC_ALLOC */ | 448 #endif /* not NEW_GC */ |
449 | 449 |
450 static pdump_block_list_elt **pdump_hash; | 450 static pdump_block_list_elt **pdump_hash; |
451 | 451 |
452 #ifndef MC_ALLOC | 452 #ifndef NEW_GC |
453 /* Since most pointers are eight bytes aligned, the >>3 allows for a better hash */ | 453 /* Since most pointers are eight bytes aligned, the >>3 allows for a better hash */ |
454 #endif /* not MC_ALLOC */ | 454 #endif /* not NEW_GC */ |
455 static int | 455 static int |
456 pdump_make_hash (const void *obj) | 456 pdump_make_hash (const void *obj) |
457 { | 457 { |
458 #ifdef MC_ALLOC | 458 #ifdef NEW_GC |
459 return ((unsigned long)(obj) * PDUMP_HASH_MULTIPLIER) % PDUMP_HASHSIZE; | 459 return ((unsigned long)(obj) * PDUMP_HASH_MULTIPLIER) % PDUMP_HASHSIZE; |
460 #else /* not MC_ALLOC */ | 460 #else /* not NEW_GC */ |
461 return ((unsigned long)(obj)>>3) % PDUMP_HASHSIZE; | 461 return ((unsigned long)(obj)>>3) % PDUMP_HASHSIZE; |
462 #endif /* not MC_ALLOC */ | 462 #endif /* not NEW_GC */ |
463 } | 463 } |
464 | 464 |
465 /* Return the entry for an already-registered memory block at OBJ, | 465 /* Return the entry for an already-registered memory block at OBJ, |
466 or NULL if none. */ | 466 or NULL if none. */ |
467 | 467 |
522 if (align < list->align) | 522 if (align < list->align) |
523 list->align = align; | 523 list->align = align; |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 #ifdef MC_ALLOC | 527 #ifdef NEW_GC |
528 typedef struct mc_addr_elt | 528 typedef struct mc_addr_elt |
529 { | 529 { |
530 const void *obj; | 530 const void *obj; |
531 EMACS_INT addr; | 531 EMACS_INT addr; |
532 } mc_addr_elt; | 532 } mc_addr_elt; |
585 } | 585 } |
586 | 586 |
587 pdump_mc_hash[pos].obj = obj; | 587 pdump_mc_hash[pos].obj = obj; |
588 pdump_mc_hash[pos].addr = addr; | 588 pdump_mc_hash[pos].addr = addr; |
589 } | 589 } |
590 #endif /* MC_ALLOC */ | 590 #endif /* NEW_GC */ |
591 | 591 |
592 static pdump_block_list * | 592 static pdump_block_list * |
593 pdump_get_block_list (const struct memory_description *desc) | 593 pdump_get_block_list (const struct memory_description *desc) |
594 { | 594 { |
595 int i; | 595 int i; |
684 backtrace[me].position = 0; | 684 backtrace[me].position = 0; |
685 backtrace[me].offset = 0; | 685 backtrace[me].offset = 0; |
686 } | 686 } |
687 | 687 |
688 static void pdump_register_object (Lisp_Object obj); | 688 static void pdump_register_object (Lisp_Object obj); |
689 #ifdef NEW_GC | |
690 static void pdump_register_object_array (Lisp_Object data, | |
691 Bytecount size, | |
692 const struct memory_description *desc, | |
693 int count); | |
694 #endif /* NEW_GC */ | |
689 static void pdump_register_block_contents (const void *data, | 695 static void pdump_register_block_contents (const void *data, |
690 Bytecount size, | 696 Bytecount size, |
691 const struct memory_description * | 697 const struct memory_description * |
692 desc, | 698 desc, |
693 int count); | 699 int count); |
779 (const Rawbyte *) pobj - (const Rawbyte *) data; | 785 (const Rawbyte *) pobj - (const Rawbyte *) data; |
780 pdump_register_object (dobj); | 786 pdump_register_object (dobj); |
781 } | 787 } |
782 break; | 788 break; |
783 } | 789 } |
790 #ifdef NEW_GC | |
791 case XD_LISP_OBJECT_BLOCK_PTR: | |
792 { | |
793 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | |
794 data); | |
795 const struct sized_memory_description *sdesc = | |
796 lispdesc_indirect_description (data, desc1->data2.descr); | |
797 const Lisp_Object *pobj = (const Lisp_Object *) rdata; | |
798 if (pobj) | |
799 pdump_register_object_array | |
800 (*pobj, sdesc->size, sdesc->description, count); | |
801 break; | |
802 } | |
803 #endif /* NEW_GC */ | |
784 case XD_BLOCK_PTR: | 804 case XD_BLOCK_PTR: |
785 { | 805 { |
786 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, | 806 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
787 data); | 807 data); |
788 const struct sized_memory_description *sdesc = | 808 const struct sized_memory_description *sdesc = |
857 return; | 877 return; |
858 | 878 |
859 imp = LHEADER_IMPLEMENTATION (objh); | 879 imp = LHEADER_IMPLEMENTATION (objh); |
860 | 880 |
861 if (imp->description | 881 if (imp->description |
882 #ifdef NEW_GC | |
883 /* Objects with finalizers cannot be dumped with the new | |
884 allocator's asynchronous finalization strategy. */ | |
885 && !imp->finalizer | |
886 #endif /* not NEW_GC */ | |
862 && RECORD_DUMPABLE (objh)) | 887 && RECORD_DUMPABLE (objh)) |
863 { | 888 { |
864 pdump_bump_depth (); | 889 pdump_bump_depth (); |
865 backtrace[pdump_depth - 1].obj = objh; | 890 backtrace[pdump_depth - 1].obj = objh; |
866 pdump_add_block (pdump_object_table + objh->type, | 891 pdump_add_block (pdump_object_table + objh->type, |
873 pdump_alert_undump_object[objh->type]++; | 898 pdump_alert_undump_object[objh->type]++; |
874 stderr_out ("Undumpable object type : %s\n", imp->name); | 899 stderr_out ("Undumpable object type : %s\n", imp->name); |
875 pdump_backtrace (); | 900 pdump_backtrace (); |
876 } | 901 } |
877 } | 902 } |
903 | |
904 #ifdef NEW_GC | |
905 static void | |
906 pdump_register_object_array (Lisp_Object obj, | |
907 Bytecount size, | |
908 const struct memory_description *desc, | |
909 int count) | |
910 { | |
911 struct lrecord_header *objh; | |
912 const struct lrecord_implementation *imp; | |
913 | |
914 if (!POINTER_TYPE_P (XTYPE (obj))) | |
915 return; | |
916 | |
917 objh = XRECORD_LHEADER (obj); | |
918 if (!objh) | |
919 return; | |
920 | |
921 if (pdump_get_block (objh)) | |
922 return; | |
923 | |
924 imp = LHEADER_IMPLEMENTATION (objh); | |
925 | |
926 if (imp->description | |
927 && RECORD_DUMPABLE (objh)) | |
928 { | |
929 pdump_bump_depth (); | |
930 backtrace[pdump_depth - 1].obj = objh; | |
931 pdump_add_block (pdump_object_table + objh->type, | |
932 objh, lispdesc_block_size_1 (objh, size, desc), count); | |
933 pdump_register_block_contents (objh, size, desc, count); | |
934 --pdump_depth; | |
935 } | |
936 else | |
937 { | |
938 pdump_alert_undump_object[objh->type]++; | |
939 stderr_out ("Undumpable object type : %s\n", imp->name); | |
940 pdump_backtrace (); | |
941 } | |
942 } | |
943 #endif /* NEW_GC */ | |
878 | 944 |
879 /* Register the referenced objects in the array of COUNT blocks located at | 945 /* Register the referenced objects in the array of COUNT blocks located at |
880 DATA; each block is described by SIZE and DESC. "Block" here simply | 946 DATA; each block is described by SIZE and DESC. "Block" here simply |
881 means any block of memory. | 947 means any block of memory. |
882 | 948 |
992 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, | 1058 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, |
993 orig_data); | 1059 orig_data); |
994 * (int *) rdata = val; | 1060 * (int *) rdata = val; |
995 break; | 1061 break; |
996 } | 1062 } |
1063 #ifdef NEW_GC | |
1064 case XD_LISP_OBJECT_BLOCK_PTR: | |
1065 #endif /* NEW_GC */ | |
997 case XD_OPAQUE_DATA_PTR: | 1066 case XD_OPAQUE_DATA_PTR: |
998 case XD_ASCII_STRING: | 1067 case XD_ASCII_STRING: |
999 case XD_BLOCK_PTR: | 1068 case XD_BLOCK_PTR: |
1000 { | 1069 { |
1001 void *ptr = * (void **) rdata; | 1070 void *ptr = * (void **) rdata; |
1134 pdump_store_new_pointer_offsets (count, pdump_buf, elt->obj, desc, size); | 1203 pdump_store_new_pointer_offsets (count, pdump_buf, elt->obj, desc, size); |
1135 } | 1204 } |
1136 retry_fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out); | 1205 retry_fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out); |
1137 } | 1206 } |
1138 | 1207 |
1139 #ifdef MC_ALLOC | 1208 #ifdef NEW_GC |
1140 /* To be able to relocate during load time, more information about the | 1209 /* To be able to relocate during load time, more information about the |
1141 dumped objects are needed: The count (for array-like data | 1210 dumped objects are needed: The count (for array-like data |
1142 structures), the size of the object, and the location in the dumped | 1211 structures), the size of the object, and the location in the dumped |
1143 data. | 1212 data. |
1144 */ | 1213 */ |
1171 | 1240 |
1172 for (i=0; i<lrecord_type_count; i++) | 1241 for (i=0; i<lrecord_type_count; i++) |
1173 if (pdump_object_table[i].align == align) | 1242 if (pdump_object_table[i].align == align) |
1174 for (elt = pdump_object_table[i].first; elt; elt = elt->next) | 1243 for (elt = pdump_object_table[i].first; elt; elt = elt->next) |
1175 { | 1244 { |
1176 assert (elt->count == 1); | |
1177 f (elt, lrecord_implementations_table[i]->description); | 1245 f (elt, lrecord_implementations_table[i]->description); |
1178 } | 1246 } |
1179 } | 1247 } |
1180 } | 1248 } |
1181 | 1249 |
1232 case XD_HASHCODE: | 1300 case XD_HASHCODE: |
1233 case XD_INT: | 1301 case XD_INT: |
1234 case XD_LONG: | 1302 case XD_LONG: |
1235 case XD_INT_RESET: | 1303 case XD_INT_RESET: |
1236 break; | 1304 break; |
1305 case XD_LISP_OBJECT_BLOCK_PTR: | |
1237 case XD_OPAQUE_DATA_PTR: | 1306 case XD_OPAQUE_DATA_PTR: |
1238 case XD_ASCII_STRING: | 1307 case XD_ASCII_STRING: |
1239 case XD_BLOCK_PTR: | 1308 case XD_BLOCK_PTR: |
1240 case XD_LO_LINK: | 1309 case XD_LO_LINK: |
1241 { | 1310 { |
1250 | 1319 |
1251 assert (desc1->data1 == 0); | 1320 assert (desc1->data1 == 0); |
1252 | 1321 |
1253 if (POINTER_TYPE_P (XTYPE (*pobj)) | 1322 if (POINTER_TYPE_P (XTYPE (*pobj)) |
1254 && ! EQ (*pobj, Qnull_pointer)) | 1323 && ! EQ (*pobj, Qnull_pointer)) |
1255 *pobj = wrap_pointer_1 ((char *) pdump_get_mc_addr | 1324 *pobj = wrap_pointer_1 ((Rawbyte *) pdump_get_mc_addr |
1256 (XPNTR (*pobj))); | 1325 (XPNTR (*pobj))); |
1257 break; | 1326 break; |
1258 } | 1327 } |
1259 case XD_LISP_OBJECT_ARRAY: | 1328 case XD_LISP_OBJECT_ARRAY: |
1260 { | 1329 { |
1266 { | 1335 { |
1267 Lisp_Object *pobj = (Lisp_Object *) rdata + j; | 1336 Lisp_Object *pobj = (Lisp_Object *) rdata + j; |
1268 | 1337 |
1269 if (POINTER_TYPE_P (XTYPE (*pobj)) | 1338 if (POINTER_TYPE_P (XTYPE (*pobj)) |
1270 && ! EQ (*pobj, Qnull_pointer)) | 1339 && ! EQ (*pobj, Qnull_pointer)) |
1271 *pobj = wrap_pointer_1 ((char *) pdump_get_mc_addr | 1340 *pobj = wrap_pointer_1 ((Rawbyte *) pdump_get_mc_addr |
1272 (XPNTR (*pobj))); | 1341 (XPNTR (*pobj))); |
1273 } | 1342 } |
1274 break; | 1343 break; |
1275 } | 1344 } |
1276 case XD_DOC_STRING: | 1345 case XD_DOC_STRING: |
1334 default: | 1403 default: |
1335 pdump_unsupported_dump_type (desc1->type, 0); | 1404 pdump_unsupported_dump_type (desc1->type, 0); |
1336 } | 1405 } |
1337 } | 1406 } |
1338 } | 1407 } |
1339 #else /* not MC_ALLOC */ | 1408 #else /* not NEW_GC */ |
1340 /* Relocate a single memory block at DATA, described by DESC, from its | 1409 /* Relocate a single memory block at DATA, described by DESC, from its |
1341 assumed load location to its actual one by adding DELTA to all pointers | 1410 assumed load location to its actual one by adding DELTA to all pointers |
1342 in the block. Does not recursively relocate any other memory blocks | 1411 in the block. Does not recursively relocate any other memory blocks |
1343 pointed to. (We already have a list of all memory blocks in the dump | 1412 pointed to. (We already have a list of all memory blocks in the dump |
1344 file.) This is used once the dump data has been loaded back in, both | 1413 file.) This is used once the dump data has been loaded back in, both |
1468 default: | 1537 default: |
1469 pdump_unsupported_dump_type (desc1->type, 0); | 1538 pdump_unsupported_dump_type (desc1->type, 0); |
1470 } | 1539 } |
1471 } | 1540 } |
1472 } | 1541 } |
1473 #endif /* not MC_ALLOC */ | 1542 #endif /* not NEW_GC */ |
1474 | 1543 |
1475 static void | 1544 static void |
1476 pdump_allocate_offset (pdump_block_list_elt *elt, | 1545 pdump_allocate_offset (pdump_block_list_elt *elt, |
1477 const struct memory_description *UNUSED (desc)) | 1546 const struct memory_description *UNUSED (desc)) |
1478 { | 1547 { |
1601 | 1670 |
1602 PDUMP_ALIGN_OUTPUT (pdump_cv_data_dump_info); | 1671 PDUMP_ALIGN_OUTPUT (pdump_cv_data_dump_info); |
1603 retry_fwrite (data, sizeof (pdump_cv_data_dump_info), count, pdump_out); | 1672 retry_fwrite (data, sizeof (pdump_cv_data_dump_info), count, pdump_out); |
1604 } | 1673 } |
1605 | 1674 |
1675 static void | |
1676 pdump_dump_cv_ptr_info (void) | |
1677 { | |
1678 int i; | |
1679 Elemcount count = Dynarr_length (pdump_cv_ptr); | |
1680 pdump_cv_ptr_dump_info *data = alloca_array (pdump_cv_ptr_dump_info, count); | |
1681 for (i = 0; i < count; i++) | |
1682 { | |
1683 data[i].save_offset = Dynarr_at (pdump_cv_ptr, i).save_offset; | |
1684 data[i].size = Dynarr_at (pdump_cv_ptr, i).size; | |
1685 } | |
1686 | |
1687 PDUMP_ALIGN_OUTPUT (pdump_cv_ptr_dump_info); | |
1688 retry_fwrite (data, sizeof (pdump_cv_ptr_dump_info), count, pdump_out); | |
1689 } | |
1690 | |
1606 /* Dump out the root block pointers, part of stage 3 (the "WRITE" stage) of | 1691 /* Dump out the root block pointers, part of stage 3 (the "WRITE" stage) of |
1607 dumping. For each pointer we dump out a structure containing the | 1692 dumping. For each pointer we dump out a structure containing the |
1608 location of the pointer and its value, replaced by the appropriate | 1693 location of the pointer and its value, replaced by the appropriate |
1609 offset into the dumped data. */ | 1694 offset into the dumped data. */ |
1610 | |
1611 static void | |
1612 pdump_dump_cv_ptr_info (void) | |
1613 { | |
1614 int i; | |
1615 Elemcount count = Dynarr_length (pdump_cv_ptr); | |
1616 pdump_cv_ptr_dump_info *data = alloca_array (pdump_cv_ptr_dump_info, count); | |
1617 for (i = 0; i < count; i++) | |
1618 { | |
1619 data[i].save_offset = Dynarr_at (pdump_cv_ptr, i).save_offset; | |
1620 data[i].size = Dynarr_at (pdump_cv_ptr, i).size; | |
1621 } | |
1622 | |
1623 PDUMP_ALIGN_OUTPUT (pdump_cv_ptr_dump_info); | |
1624 retry_fwrite (data, sizeof (pdump_cv_ptr_dump_info), count, pdump_out); | |
1625 } | |
1626 | 1695 |
1627 static void | 1696 static void |
1628 pdump_dump_root_block_ptrs (void) | 1697 pdump_dump_root_block_ptrs (void) |
1629 { | 1698 { |
1630 int i; | 1699 int i; |
1685 rt.count = pdump_object_table[i].count; | 1754 rt.count = pdump_object_table[i].count; |
1686 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); | 1755 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
1687 while (elt) | 1756 while (elt) |
1688 { | 1757 { |
1689 EMACS_INT rdata = pdump_get_block (elt->obj)->save_offset; | 1758 EMACS_INT rdata = pdump_get_block (elt->obj)->save_offset; |
1759 #ifdef NEW_GC | |
1760 int j; | |
1761 for (j=0; j<elt->count; j++) | |
1762 { | |
1763 PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); | |
1764 rdata += elt->size; | |
1765 } | |
1766 #else /* not NEW_GC */ | |
1690 PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); | 1767 PDUMP_WRITE_ALIGNED (EMACS_INT, rdata); |
1768 #endif /* not NEW_GC */ | |
1691 elt = elt->next; | 1769 elt = elt->next; |
1692 } | 1770 } |
1693 } | 1771 } |
1694 | 1772 |
1695 rt.desc = 0; | 1773 rt.desc = 0; |
2080 elt->fcts->convert_free(elt->object, elt->data, elt->size); | 2158 elt->fcts->convert_free(elt->object, elt->data, elt->size); |
2081 } | 2159 } |
2082 | 2160 |
2083 fseek (pdump_out, header.stab_offset, SEEK_SET); | 2161 fseek (pdump_out, header.stab_offset, SEEK_SET); |
2084 | 2162 |
2085 #ifdef MC_ALLOC | 2163 #ifdef NEW_GC |
2086 { | 2164 { |
2087 EMACS_INT zero = 0; | 2165 EMACS_INT zero = 0; |
2088 pdump_scan_lisp_objects_by_alignment (pdump_dump_mc_data); | 2166 pdump_scan_lisp_objects_by_alignment (pdump_dump_mc_data); |
2089 PDUMP_WRITE_ALIGNED (EMACS_INT, zero); | 2167 PDUMP_WRITE_ALIGNED (EMACS_INT, zero); |
2090 pdump_scan_non_lisp_objects_by_alignment (pdump_dump_mc_data); | 2168 pdump_scan_non_lisp_objects_by_alignment (pdump_dump_mc_data); |
2091 PDUMP_WRITE_ALIGNED (EMACS_INT, zero); | 2169 PDUMP_WRITE_ALIGNED (EMACS_INT, zero); |
2092 } | 2170 } |
2093 #endif /* MC_ALLOC */ | 2171 #endif /* NEW_GC */ |
2094 pdump_dump_cv_data_info (); | 2172 pdump_dump_cv_data_info (); |
2095 pdump_dump_cv_ptr_info (); | 2173 pdump_dump_cv_ptr_info (); |
2096 #ifdef MC_ALLOC | 2174 #ifdef NEW_GC |
2097 pdump_dump_rtables (); | 2175 pdump_dump_rtables (); |
2098 #endif /* MC_ALLOC */ | 2176 #endif /* NEW_GC */ |
2099 pdump_dump_root_block_ptrs (); | 2177 pdump_dump_root_block_ptrs (); |
2100 pdump_dump_root_blocks (); | 2178 pdump_dump_root_blocks (); |
2101 #ifndef MC_ALLOC | 2179 #ifndef NEW_GC |
2102 pdump_dump_rtables (); | 2180 pdump_dump_rtables (); |
2103 #endif /* not MC_ALLOC */ | 2181 #endif /* not NEW_GC */ |
2104 pdump_dump_root_lisp_objects (); | 2182 pdump_dump_root_lisp_objects (); |
2105 | 2183 |
2106 retry_fclose (pdump_out); | 2184 retry_fclose (pdump_out); |
2107 retry_close (pdump_fd); | 2185 /* pdump_fd is already closed by the preceding call to fclose. |
2186 retry_close (pdump_fd); */ | |
2108 | 2187 |
2109 free (pdump_buf); | 2188 free (pdump_buf); |
2110 | 2189 |
2111 free (pdump_hash); | 2190 free (pdump_hash); |
2112 | 2191 |
2134 Rawbyte *p; | 2213 Rawbyte *p; |
2135 EMACS_INT delta; | 2214 EMACS_INT delta; |
2136 EMACS_INT count; | 2215 EMACS_INT count; |
2137 pdump_header *header = (pdump_header *) pdump_start; | 2216 pdump_header *header = (pdump_header *) pdump_start; |
2138 | 2217 |
2218 #ifdef NEW_GC | |
2219 /* This is a DEFVAR_BOOL and gets dumped, but the actual value was | |
2220 already determined by vdb_install_signal_handler () in | |
2221 vdb-mprotect.c, which could be different from the value in the | |
2222 dump file. So store it here and restore it after loading the dump | |
2223 file. */ | |
2224 int allow_inc_gc = allow_incremental_gc; | |
2225 #endif /* NEW_GC */ | |
2139 pdump_end = pdump_start + pdump_length; | 2226 pdump_end = pdump_start + pdump_length; |
2140 | 2227 |
2141 delta = ((EMACS_INT) pdump_start) - header->reloc_address; | 2228 delta = ((EMACS_INT) pdump_start) - header->reloc_address; |
2142 p = pdump_start + header->stab_offset; | 2229 p = pdump_start + header->stab_offset; |
2143 | 2230 |
2144 #ifdef MC_ALLOC | 2231 #ifdef NEW_GC |
2145 pdump_mc_hash = xnew_array_and_zero (mc_addr_elt, PDUMP_HASHSIZE); | 2232 pdump_mc_hash = xnew_array_and_zero (mc_addr_elt, PDUMP_HASHSIZE); |
2146 | 2233 |
2147 /* Allocate space for each object individually. First the | 2234 /* Allocate space for each object individually. First the |
2148 Lisp_Objects, then the blocks. */ | 2235 Lisp_Objects, then the blocks. */ |
2149 count = 2; | 2236 count = 2; |
2161 if (i == 0) | 2248 if (i == 0) |
2162 { | 2249 { |
2163 Bytecount real_size = size * elt_count; | 2250 Bytecount real_size = size * elt_count; |
2164 if (count == 2) | 2251 if (count == 2) |
2165 { | 2252 { |
2166 mc_addr = (Rawbyte *) mc_alloc (real_size); | 2253 if (elt_count <= 1) |
2254 mc_addr = (Rawbyte *) mc_alloc (real_size); | |
2255 else | |
2256 mc_addr = (Rawbyte *) mc_alloc_array (size, elt_count); | |
2167 #ifdef ALLOC_TYPE_STATS | 2257 #ifdef ALLOC_TYPE_STATS |
2168 inc_lrecord_stats (real_size, | 2258 inc_lrecord_stats (real_size, |
2169 (const struct lrecord_header *) | 2259 (const struct lrecord_header *) |
2170 ((char *) rdata + delta)); | 2260 ((Rawbyte *) rdata + delta)); |
2171 if (((const struct lrecord_header *) | |
2172 ((char *) rdata + delta))->type | |
2173 == lrecord_type_string) | |
2174 inc_lrecord_string_data_stats | |
2175 (((Lisp_String *) ((char *) rdata + delta))->size_); | |
2176 #endif /* ALLOC_TYPE_STATS */ | 2261 #endif /* ALLOC_TYPE_STATS */ |
2177 } | 2262 } |
2178 else | 2263 else |
2179 mc_addr = (Rawbyte *) xmalloc_and_zero (real_size); | 2264 mc_addr = (Rawbyte *) xmalloc_and_zero (real_size); |
2180 } | 2265 } |
2181 else | 2266 else |
2182 mc_addr += size; | 2267 mc_addr += size; |
2183 | 2268 |
2184 pdump_put_mc_addr ((void *) rdata, (EMACS_INT) mc_addr); | 2269 pdump_put_mc_addr ((void *) rdata, (EMACS_INT) mc_addr); |
2185 memcpy (mc_addr, (char *) rdata + delta, size); | 2270 memcpy (mc_addr, (Rawbyte *) rdata + delta, size); |
2186 } | 2271 } |
2187 } | 2272 } |
2188 else if (!(--count)) | 2273 else if (!(--count)) |
2189 break; | 2274 break; |
2190 } | 2275 } |
2191 #endif /* MC_ALLOC */ | 2276 #endif /* NEW_GC */ |
2192 | 2277 |
2193 /* Get the cv_data array */ | 2278 /* Get the cv_data array */ |
2194 p = (Rawbyte *) ALIGN_PTR (p, pdump_cv_data_dump_info); | 2279 p = (Rawbyte *) ALIGN_PTR (p, pdump_cv_data_dump_info); |
2195 pdump_loaded_cv_data = (pdump_cv_data_dump_info *)p; | 2280 pdump_loaded_cv_data = (pdump_cv_data_dump_info *)p; |
2196 p += header->nb_cv_data*sizeof(pdump_cv_data_dump_info); | 2281 p += header->nb_cv_data*sizeof(pdump_cv_data_dump_info); |
2205 pdump_loaded_cv_ptr[i].save_offset = info.save_offset; | 2290 pdump_loaded_cv_ptr[i].save_offset = info.save_offset; |
2206 pdump_loaded_cv_ptr[i].size = info.size; | 2291 pdump_loaded_cv_ptr[i].size = info.size; |
2207 pdump_loaded_cv_ptr[i].adr = 0; | 2292 pdump_loaded_cv_ptr[i].adr = 0; |
2208 } | 2293 } |
2209 | 2294 |
2210 #ifdef MC_ALLOC | 2295 #ifdef NEW_GC |
2211 /* Relocate the heap objects */ | 2296 /* Relocate the heap objects */ |
2212 pdump_rt_list = p; | 2297 pdump_rt_list = p; |
2213 count = 2; | 2298 count = 2; |
2214 for (;;) | 2299 for (;;) |
2215 { | 2300 { |
2216 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); | 2301 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); |
2217 p = (Rawbyte *) ALIGN_PTR (p, Rawbyte *); | 2302 p = (Rawbyte *) ALIGN_PTR (p, Rawbyte *); |
2218 if (rt.desc) | 2303 if (rt.desc) |
2219 { | 2304 { |
2220 char **reloc = (char **) p; | 2305 Rawbyte **reloc = (Rawbyte **) p; |
2221 for (i = 0; i < rt.count; i++) | 2306 for (i = 0; i < rt.count; i++) |
2222 { | 2307 { |
2223 reloc[i] = (char *) pdump_get_mc_addr (reloc[i]); | 2308 reloc[i] = (Rawbyte *) pdump_get_mc_addr (reloc[i]); |
2224 pdump_reloc_one_mc (reloc[i], rt.desc); | 2309 pdump_reloc_one_mc (reloc[i], rt.desc); |
2225 } | 2310 } |
2226 p += rt.count * sizeof (char *); | 2311 p += rt.count * sizeof (Rawbyte *); |
2227 } | 2312 } |
2228 else if (!(--count)) | 2313 else if (!(--count)) |
2229 break; | 2314 break; |
2230 } | 2315 } |
2231 #endif /* MC_ALLOC */ | 2316 #endif /* NEW_GC */ |
2232 | 2317 |
2233 /* Put back the pdump_root_block_ptrs */ | 2318 /* Put back the pdump_root_block_ptrs */ |
2234 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_pointer); | 2319 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_pointer); |
2235 for (i = 0; i < header->nb_root_block_ptrs; i++) | 2320 for (i = 0; i < header->nb_root_block_ptrs; i++) |
2236 { | 2321 { |
2237 pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); | 2322 pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); |
2238 #ifdef MC_ALLOC | 2323 #ifdef NEW_GC |
2239 (* ptr.address) = (Rawbyte *) pdump_get_mc_addr (ptr.value); | 2324 (* ptr.address) = (Rawbyte *) pdump_get_mc_addr (ptr.value); |
2240 #else /* not MC_ALLOC */ | 2325 #else /* not NEW_GC */ |
2241 (* ptr.address) = ptr.value + delta; | 2326 (* ptr.address) = ptr.value + delta; |
2242 #endif /* not MC_ALLOC */ | 2327 #endif /* not NEW_GC */ |
2243 } | 2328 } |
2244 | 2329 |
2245 /* Put back the pdump_root_blocks and relocate */ | 2330 /* Put back the pdump_root_blocks and relocate */ |
2246 for (i = 0; i < header->nb_root_blocks; i++) | 2331 for (i = 0; i < header->nb_root_blocks; i++) |
2247 { | 2332 { |
2248 pdump_root_block info = PDUMP_READ_ALIGNED (p, pdump_root_block); | 2333 pdump_root_block info = PDUMP_READ_ALIGNED (p, pdump_root_block); |
2249 memcpy ((void *) info.blockaddr, p, info.size); | 2334 memcpy ((void *) info.blockaddr, p, info.size); |
2250 if (info.desc) | 2335 if (info.desc) |
2251 #ifdef MC_ALLOC | 2336 #ifdef NEW_GC |
2252 pdump_reloc_one_mc ((void *) info.blockaddr, info.desc); | 2337 pdump_reloc_one_mc ((void *) info.blockaddr, info.desc); |
2253 #else /* not MC_ALLOC */ | 2338 #else /* not NEW_GC */ |
2254 pdump_reloc_one ((void *) info.blockaddr, delta, info.desc); | 2339 pdump_reloc_one ((void *) info.blockaddr, delta, info.desc); |
2255 #endif /* not MC_ALLOC */ | 2340 #endif /* not NEW_GC */ |
2256 p += info.size; | 2341 p += info.size; |
2257 } | 2342 } |
2258 | 2343 |
2259 #ifndef MC_ALLOC | 2344 #ifndef NEW_GC |
2260 /* Relocate the heap objects */ | 2345 /* Relocate the heap objects */ |
2261 pdump_rt_list = p; | 2346 pdump_rt_list = p; |
2262 count = 2; | 2347 count = 2; |
2263 for (;;) | 2348 for (;;) |
2264 { | 2349 { |
2275 p += rt.count * sizeof (Rawbyte *); | 2360 p += rt.count * sizeof (Rawbyte *); |
2276 } | 2361 } |
2277 else if (!(--count)) | 2362 else if (!(--count)) |
2278 break; | 2363 break; |
2279 } | 2364 } |
2280 #endif /* not MC_ALLOC */ | 2365 #endif /* not NEW_GC */ |
2281 | 2366 |
2282 /* Put the pdump_root_lisp_objects variables in place */ | 2367 /* Put the pdump_root_lisp_objects variables in place */ |
2283 i = PDUMP_READ_ALIGNED (p, Elemcount); | 2368 i = PDUMP_READ_ALIGNED (p, Elemcount); |
2284 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_Lisp_Object); | 2369 p = (Rawbyte *) ALIGN_PTR (p, pdump_static_Lisp_Object); |
2285 while (i--) | 2370 while (i--) |
2286 { | 2371 { |
2287 pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); | 2372 pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); |
2288 | 2373 |
2289 if (POINTER_TYPE_P (XTYPE (obj.value))) | 2374 if (POINTER_TYPE_P (XTYPE (obj.value))) |
2290 #ifdef MC_ALLOC | 2375 #ifdef NEW_GC |
2291 obj.value = wrap_pointer_1 ((Rawbyte *) pdump_get_mc_addr | 2376 obj.value = wrap_pointer_1 ((Rawbyte *) pdump_get_mc_addr |
2292 (XPNTR (obj.value))); | 2377 (XPNTR (obj.value))); |
2293 #else /* not MC_ALLOC */ | 2378 #else /* not NEW_GC */ |
2294 obj.value = wrap_pointer_1 ((Rawbyte *) XPNTR (obj.value) + delta); | 2379 obj.value = wrap_pointer_1 ((Rawbyte *) XPNTR (obj.value) + delta); |
2295 #endif /* not MC_ALLOC */ | 2380 #endif /* not NEW_GC */ |
2296 | 2381 |
2297 (* obj.address) = obj.value; | 2382 (* obj.address) = obj.value; |
2298 } | 2383 } |
2299 | 2384 |
2300 /* Final cleanups */ | 2385 /* Final cleanups */ |
2314 } | 2399 } |
2315 else | 2400 else |
2316 p += sizeof (Lisp_Object) * rt.count; | 2401 p += sizeof (Lisp_Object) * rt.count; |
2317 } | 2402 } |
2318 | 2403 |
2319 #ifdef MC_ALLOC | 2404 #ifdef NEW_GC |
2320 xfree (pdump_mc_hash, mc_addr_elt *); | 2405 xfree (pdump_mc_hash, mc_addr_elt *); |
2321 #endif /* MC_ALLOC */ | 2406 #endif /* NEW_GC */ |
2407 | |
2408 #ifdef NEW_GC | |
2409 allow_incremental_gc = allow_inc_gc; | |
2410 #endif /* NEW_GC */ | |
2322 | 2411 |
2323 return 1; | 2412 return 1; |
2324 } | 2413 } |
2325 | 2414 |
2326 #ifdef WIN32_NATIVE | 2415 #ifdef WIN32_NATIVE |
2539 } | 2628 } |
2540 while (w > exe_path && !IS_DIRECTORY_SEP (*w)); | 2629 while (w > exe_path && !IS_DIRECTORY_SEP (*w)); |
2541 return 0; | 2630 return 0; |
2542 } | 2631 } |
2543 | 2632 |
2633 #define DUMP_SLACK 100 /* Enough to include dump ID, version name, .DMP */ | |
2634 | |
2544 int | 2635 int |
2545 pdump_load (const Wexttext *argv0) | 2636 pdump_load (const Wexttext *argv0) |
2546 { | 2637 { |
2547 #ifdef WIN32_NATIVE | 2638 #ifdef WIN32_NATIVE |
2548 Wexttext *exe_path = NULL; | 2639 Wexttext *exe_path = NULL; |
2549 int bufsize = 4096; | 2640 int bufsize = 4096; |
2550 int cchpathsize; | 2641 int cchpathsize; |
2551 #define DUMP_SLACK 100 /* Enough to include dump ID, version name, .DMP */ | |
2552 | 2642 |
2553 /* Copied from mswindows_get_module_file_name (). Not clear if it's | 2643 /* Copied from mswindows_get_module_file_name (). Not clear if it's |
2554 kosher to malloc() yet. */ | 2644 kosher to malloc() yet. */ |
2555 while (1) | 2645 while (1) |
2556 { | 2646 { |
2602 p--; | 2692 p--; |
2603 | 2693 |
2604 if (p != dir) | 2694 if (p != dir) |
2605 { | 2695 { |
2606 /* invocation-name includes a directory component -- presumably it | 2696 /* invocation-name includes a directory component -- presumably it |
2607 is relative to cwd, not $PATH */ | 2697 is relative to cwd, not $PATH. */ |
2608 exe_path = alloca_array (Wexttext, 1 + wext_strlen (dir)); | 2698 exe_path = alloca_array (Wexttext, 1 + wext_strlen (dir) + DUMP_SLACK); |
2609 wext_strcpy (exe_path, dir); | 2699 wext_strcpy (exe_path, dir); |
2610 } | 2700 } |
2611 else | 2701 else |
2612 { | 2702 { |
2613 const Wexttext *path = wext_getenv ("PATH"); /* not egetenv -- | 2703 const Wexttext *path = wext_getenv ("PATH"); /* not egetenv -- |
2614 not yet init. */ | 2704 not yet init. */ |
2615 const Wexttext *name = p; | 2705 const Wexttext *name = p; |
2616 exe_path = alloca_array (Wexttext, | 2706 exe_path = alloca_array (Wexttext, |
2617 10 + max (wext_strlen (name), | 2707 1 + DUMP_SLACK + max (wext_strlen (name), |
2618 wext_strlen (path))); | 2708 wext_strlen (path))); |
2619 for (;;) | 2709 for (;;) |
2620 { | 2710 { |
2621 p = path; | 2711 p = path; |
2622 while (*p && *p != SEPCHAR) | 2712 while (*p && *p != SEPCHAR) |
2623 p++; | 2713 p++; |
2656 | 2746 |
2657 if (pdump_file_try (exe_path)) | 2747 if (pdump_file_try (exe_path)) |
2658 { | 2748 { |
2659 pdump_load_finish (); | 2749 pdump_load_finish (); |
2660 in_pdump = 0; | 2750 in_pdump = 0; |
2661 #ifdef MC_ALLOC | 2751 #ifdef NEW_GC |
2662 pdump_free (); | 2752 pdump_free (); |
2663 #endif /* MC_ALLOC */ | 2753 #endif /* NEW_GC */ |
2664 return 1; | 2754 return 1; |
2665 } | 2755 } |
2666 | 2756 |
2667 #ifdef WIN32_NATIVE | 2757 #ifdef WIN32_NATIVE |
2668 if (pdump_resource_get ()) | 2758 if (pdump_resource_get ()) |
2669 { | 2759 { |
2670 if (pdump_load_check ()) | 2760 if (pdump_load_check ()) |
2671 { | 2761 { |
2672 pdump_load_finish (); | 2762 pdump_load_finish (); |
2673 in_pdump = 0; | 2763 in_pdump = 0; |
2674 #ifdef MC_ALLOC | 2764 #ifdef NEW_GC |
2675 pdump_free (); | 2765 pdump_free (); |
2676 #endif /* MC_ALLOC */ | 2766 #endif /* NEW_GC */ |
2677 return 1; | 2767 return 1; |
2678 } | 2768 } |
2679 pdump_free (); | 2769 pdump_free (); |
2680 } | 2770 } |
2681 | 2771 |