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