PageRenderTime 141ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/src/data.cc

https://github.com/snmsts/xyzzy
C++ | 2902 lines | 2589 code | 311 blank | 2 comment | 381 complexity | 191fb4a8a558902d59f528a45281c887 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #include "stdafx.h"
  2. #include "ed.h"
  3. #include "lex.h"
  4. #include "symtable.h"
  5. #include "mainframe.h"
  6. lisp Qnil;
  7. lisp Qunbound;
  8. protect_gc *protect_gc::gcl;
  9. dyn_protect_gc *dyn_protect_gc::gcl;
  10. lex_env *lex_env::le;
  11. int suppress_gc::sg_suppress_p;
  12. static nonlocal_data default_nonlocal_data;
  13. nonlocal_data *nonlocal_jump::d = &default_nonlocal_data;
  14. int
  15. find_zero_bit (u_long *p, int size)
  16. {
  17. for (int i = 0; i < size; i++)
  18. if (p[i] != u_long (-1))
  19. {
  20. i *= sizeof (u_long) * CHAR_BIT;
  21. for (int ie = i + sizeof (u_long) * CHAR_BIT; i < ie; i++)
  22. if (!bitisset (p, i))
  23. return i;
  24. }
  25. return -1;
  26. }
  27. ldataP::ldataP ()
  28. : ld_heap (LDATA_PAGE_SIZE), ld_rep (0), ld_freep (0)
  29. {
  30. }
  31. ldata_rep *
  32. ldataP::alloc (int type)
  33. {
  34. ldata_rep *p = (ldata_rep *)ld_heap.alloc ();
  35. if (!p)
  36. FEstorage_error ();
  37. if (!ld_lower_bound)
  38. {
  39. ld_lower_bound = (char *)p;
  40. ld_upper_bound = (char *)p + LDATA_PAGE_SIZE;
  41. }
  42. else if ((char *)p < ld_lower_bound)
  43. ld_lower_bound = (char *)p;
  44. else if ((char *)p + LDATA_PAGE_SIZE > ld_upper_bound)
  45. ld_upper_bound = (char *)p + LDATA_PAGE_SIZE;
  46. p->dr_type = type;
  47. bzero (p->dr_used, sizeof p->dr_used);
  48. bzero (p->dr_gc, sizeof p->dr_gc);
  49. p->dr_prev = 0;
  50. if (ld_rep)
  51. ld_rep->dr_prev = p;
  52. p->dr_next = ld_rep;
  53. ld_rep = p;
  54. return p;
  55. }
  56. void
  57. ldataP::free (ldata_rep *p)
  58. {
  59. if (p->dr_prev)
  60. p->dr_prev->dr_next = p->dr_next;
  61. else
  62. ld_rep = p->dr_next;
  63. if (p->dr_next)
  64. p->dr_next->dr_prev = p->dr_prev;
  65. ld_heap.free (p);
  66. }
  67. inline void
  68. ldataP::morecore (int type, int size)
  69. {
  70. ldata_rep *p = alloc (type);
  71. char *d = p->dr_data;
  72. ld_freep = (ldata_free_rep *)d;
  73. for (char *de = d + size * (LDATASIZE_NOBJS (size) - 1); d < de; d += size)
  74. ((ldata_free_rep *)d)->lf_next = (ldata_free_rep *)(d + size);
  75. ((ldata_free_rep *)d)->lf_next = 0;
  76. }
  77. char *
  78. ldataP::do_alloc (int type, int size)
  79. {
  80. if (!ld_freep)
  81. morecore (type, size);
  82. char *r = (char *)ld_freep;
  83. ld_freep = ld_freep->lf_next;
  84. bitset (used_place (r), bit_index (r));
  85. ld_nwasted++;
  86. return r;
  87. }
  88. int
  89. ldataP::count_reps ()
  90. {
  91. int n = 0;
  92. for (ldata_rep *p = ld_rep; p; p = p->dr_next)
  93. n++;
  94. return n;
  95. }
  96. void
  97. ldataP::get_reps (ldata_rep **b)
  98. {
  99. for (ldata_rep *p = ld_rep; p; p = p->dr_next)
  100. *b++ = p;
  101. }
  102. void
  103. ldataP::alloc_reps (ldata_rep **b, int n, int f)
  104. {
  105. for (int i = 0; i < n; i++)
  106. alloc (f);
  107. for (ldata_rep *p = ld_rep; p; p = p->dr_next)
  108. *b++ = p;
  109. }
  110. int
  111. ldataP::find (void *obj, int type, int size)
  112. {
  113. if (((pointer_t (obj) & LDATA_PAGE_MASK)
  114. - offsetof (ldata_rep, dr_data)) % size)
  115. return 0;
  116. ldata_rep *r = (ldata_rep *)(pointer_t (obj) & ~LDATA_PAGE_MASK);
  117. if (r->dr_type != type)
  118. return 0;
  119. for (ldata_rep *p = ld_rep; p; p = p->dr_next)
  120. if (p == r)
  121. return 1;
  122. return 0;
  123. }
  124. static int
  125. find_object (lisp obj)
  126. {
  127. #define DECLARE_LDATA(a, b) if (ldata <a, b>::find ((char *)obj)) return 1;
  128. #include "dataP.h"
  129. return 0;
  130. }
  131. void
  132. dummy_for_instance ()
  133. {
  134. #define DECLARE_LDATA(a, b) ldata <a, b>::lalloc ();
  135. #include "dataP.h"
  136. }
  137. template <class T, u_int F>
  138. inline int
  139. ldata <T, F>::count_reps ()
  140. {
  141. return l_ld.count_reps ();
  142. }
  143. template <class T, u_int F>
  144. inline void
  145. ldata <T, F>::alloc_reps (ldata_rep **p, int n)
  146. {
  147. l_ld.alloc_reps (p, n, F);
  148. }
  149. template <class T, u_int F>
  150. inline void
  151. ldata <T, F>::get_reps (ldata_rep **b)
  152. {
  153. l_ld.get_reps (b);
  154. }
  155. void
  156. ldataP::link_unused (int size)
  157. {
  158. ld_freep = 0;
  159. for (ldata_rep *lp = ld_rep; lp; lp = lp->dr_next)
  160. for (char *d = lp->dr_data, *de = d + size * LDATASIZE_NOBJS (size);
  161. d < de; d += size)
  162. if (!bitisset (lp->dr_used, bit_index (d)))
  163. {
  164. ((ldata_free_rep *)d)->lf_next = ld_freep;
  165. ld_freep = (ldata_free_rep *)d;
  166. }
  167. }
  168. template <class T, u_int F>
  169. inline void
  170. ldata <T, F>::link_unused ()
  171. {
  172. l_ld.link_unused (sizeof (T));
  173. }
  174. void
  175. ldataP::free_all_reps ()
  176. {
  177. for (ldata_rep *p = ld_rep, *next; p; p = next)
  178. {
  179. next = p->dr_next;
  180. ld_heap.free (p);
  181. }
  182. ld_rep = 0;
  183. }
  184. template <class T, u_int F>
  185. inline void
  186. ldata <T, F>::free_all_reps ()
  187. {
  188. l_ld.free_all_reps ();
  189. }
  190. #if 0
  191. template <class T>
  192. static void
  193. delete_lisp_object (T *obj)
  194. {
  195. delete obj;
  196. }
  197. static void
  198. cleanup_object (ldata_rep *lp, u_int size, void (*delete_fn)(void *))
  199. {
  200. for (; lp; lp = lp->dr_next)
  201. for (char *d = lp->dr_data, *de = d + size * LDATASIZE_NOBJS (size);
  202. d < de; d += size)
  203. if (bitisset (lp->dr_used, bit_index (d)))
  204. (*delete_fn)(d);
  205. }
  206. template <class T, u_int F>
  207. void
  208. ldata <T, F>::cleanup ()
  209. {
  210. cleanup_object (l_ld.ld_rep, sizeof (T),
  211. (void (*)(void *))(void (*)(T *))delete_lisp_object);
  212. }
  213. static void
  214. sweep_object (ldataP &ld, u_int size, void (*delete_fn)(void *), int &xnuses, int &xnfrees)
  215. {
  216. int nuses = 0, nfrees = 0;
  217. ld.ld_freep = 0;
  218. for (ldata_rep *lp = ld.ld_rep, *next; lp; lp = next)
  219. {
  220. next = lp->dr_next;
  221. char *d = lp->dr_data;
  222. char *de = d + size * LDATASIZE_NOBJS (size);
  223. for (int i = 0; i < numberof (lp->dr_gc); i++)
  224. if (lp->dr_gc[i])
  225. goto doit;
  226. for (; d < de; d += size)
  227. if (bitisset (lp->dr_used, bit_index (d)))
  228. (*delete_fn)(d);
  229. #ifdef DEBUG_GC
  230. memset (lp->dr_data, 0, de - lp->dr_data);
  231. #endif
  232. ld.free (lp);
  233. continue;
  234. doit:
  235. for (; d < de; d += size)
  236. {
  237. int index = bit_index (d);
  238. if (bitisset (lp->dr_gc, index))
  239. {
  240. assert (bitisset (lp->dr_used, index));
  241. nuses++;
  242. bitclr (lp->dr_gc, index);
  243. }
  244. else
  245. {
  246. if (bitisset (lp->dr_used, index))
  247. {
  248. (*delete_fn)(d);
  249. bitclr (lp->dr_used, index);
  250. #ifdef DEBUG_GC
  251. memset (d, 0, size);
  252. #endif
  253. }
  254. ((ldata_free_rep *)d)->lf_next = ld.ld_freep;
  255. ld.ld_freep = (ldata_free_rep *)d;
  256. nfrees++;
  257. }
  258. }
  259. }
  260. xnuses = nuses;
  261. xnfrees = nfrees;
  262. }
  263. template <class T, u_int F>
  264. void
  265. ldata <T, F>::sweep ()
  266. {
  267. sweep_object (l_ld, sizeof (T),
  268. (void (*)(void *))(void (*)(T *))delete_lisp_object,
  269. l_nuses, l_nfrees);
  270. }
  271. #else
  272. template <class T, u_int F>
  273. void
  274. ldata <T, F>::sweep ()
  275. {
  276. l_nuses = 0;
  277. l_nfrees = 0;
  278. l_ld.ld_freep = 0;
  279. for (ldata_rep *lp = l_ld.ld_rep, *next; lp; lp = next)
  280. {
  281. next = lp->dr_next;
  282. T *d = (T *)lp->dr_data;
  283. T *de = d + LDATA_NOBJS (T);
  284. for (int i = 0; i < numberof (lp->dr_gc); i++)
  285. if (lp->dr_gc[i])
  286. goto doit;
  287. for (; d < de; d++)
  288. if (bitisset (lp->dr_used, bit_index (d)))
  289. delete d;
  290. l_ld.free (lp);
  291. continue;
  292. doit:
  293. for (; d < de; d++)
  294. {
  295. int index = bit_index (d);
  296. if (bitisset (lp->dr_gc, index))
  297. {
  298. assert (bitisset (lp->dr_used, index));
  299. l_nuses++;
  300. bitclr (lp->dr_gc, index);
  301. }
  302. else
  303. {
  304. if (bitisset (lp->dr_used, index))
  305. {
  306. delete d;
  307. bitclr (lp->dr_used, index);
  308. }
  309. ((ldata_free_rep *)d)->lf_next = l_ld.ld_freep;
  310. l_ld.ld_freep = (ldata_free_rep *)d;
  311. l_nfrees++;
  312. }
  313. }
  314. }
  315. }
  316. template <class T, u_int F>
  317. void
  318. ldata <T, F>::cleanup ()
  319. {
  320. for (ldata_rep *lp = l_ld.ld_rep; lp; lp = lp->dr_next)
  321. for (T *d = (T *)lp->dr_data, *de = d + LDATA_NOBJS (T); d < de; d++)
  322. if (bitisset (lp->dr_used, bit_index (d)))
  323. delete d;
  324. }
  325. #endif
  326. /*GENERIC_FUNCTION*/
  327. void
  328. cleanup_lisp_objects ()
  329. {
  330. #ifndef DEBUG
  331. ldata <lstream, Tstream>::cleanup ();
  332. ldata <lwin32_menu, Twin32_menu>::cleanup ();
  333. ldata <lwin32_dde_handle, Twin32_dde_handle>::cleanup ();
  334. ldata <loledata, Toledata>::cleanup ();
  335. ldata <lwait_object, Twait_object>::cleanup ();
  336. #else
  337. # define DECLARE_LDATA(a, b) ldata <a, b>::cleanup ();
  338. # include "dataP.h"
  339. #endif
  340. }
  341. template <class T, u_int F>
  342. inline lisp
  343. ldata <T, F>::countof ()
  344. {
  345. return xcons (make_fixnum (l_nuses), make_fixnum (l_nfrees));
  346. }
  347. template <class T, u_int F>
  348. inline void
  349. ldata <T, F>::unuse (T *object)
  350. {
  351. u_long *used = used_place (object);
  352. int index = bit_index (object);
  353. assert (bitisset (used, index));
  354. delete object;
  355. bitclr (used, index);
  356. ((ldata_free_rep *)object)->lf_next = l_ld.ld_freep;
  357. l_ld.ld_freep = (ldata_free_rep *)object;
  358. }
  359. static void
  360. mark_toplev_list (lisp p)
  361. {
  362. for (; consp (p); p = xcdr (p))
  363. bitset (gc_place (p), bit_index (p));
  364. }
  365. /*GENERIC_FUNCTION*/
  366. static void
  367. gc_mark_object (lisp object)
  368. {
  369. while (1)
  370. {
  371. assert (object);
  372. if (!object || immediatep (object))
  373. return;
  374. u_long *dr_gc = gc_place (object);
  375. int index = bit_index (object);
  376. if (bitisset (dr_gc, index))
  377. return;
  378. bitset (dr_gc, index);
  379. switch (object_typeof (object))
  380. {
  381. case Tcons:
  382. gc_mark_object (xcar (object));
  383. object = xcdr (object);
  384. break;
  385. case Tsymbol:
  386. gc_mark_object (xsymbol_function (object));
  387. gc_mark_object (xsymbol_plist (object));
  388. gc_mark_object (xsymbol_package (object));
  389. gc_mark_object (xsymbol_name (object));
  390. object = xsymbol_value (object);
  391. break;
  392. case Tlong_int:
  393. case Tsingle_float:
  394. case Tdouble_float:
  395. case Tbignum:
  396. return;
  397. case Tregexp:
  398. object = xregexp_source (object);
  399. break;
  400. case Tfraction:
  401. gc_mark_object (xfract_num (object));
  402. object = xfract_den (object);
  403. break;
  404. case Tcomplex:
  405. gc_mark_object (xcomplex_real (object));
  406. object = xcomplex_imag (object);
  407. break;
  408. case Tsimple_string:
  409. return;
  410. case Tsimple_vector:
  411. {
  412. lisp *p = xvector_contents (object);
  413. lisp *pe = p + xvector_length (object);
  414. for (; p < pe; p++)
  415. gc_mark_object (*p);
  416. return;
  417. }
  418. case Tcomplex_vector:
  419. {
  420. lisp *p = xvector_contents (object);
  421. lisp *pe = p + xvector_dimension (object);
  422. for (; p < pe; p++)
  423. gc_mark_object (*p);
  424. mark_toplev_list (xarray_referenced_list (object));
  425. object = xarray_displaced_to (object);
  426. break;
  427. }
  428. case Tarray:
  429. {
  430. lisp *p = xgeneral_array_contents (object);
  431. lisp *pe = p + xarray_total_size (object);
  432. for (; p < pe; p++)
  433. gc_mark_object (*p);
  434. mark_toplev_list (xarray_referenced_list (object));
  435. object = xarray_displaced_to (object);
  436. break;
  437. }
  438. case Tcomplex_string:
  439. case Tstring_array:
  440. mark_toplev_list (xarray_referenced_list (object));
  441. object = xarray_displaced_to (object);
  442. break;
  443. case Tfunction:
  444. object = xfunction_name (object);
  445. break;
  446. case Tclosure:
  447. gc_mark_object (xclosure_vars (object));
  448. gc_mark_object (xclosure_fns (object));
  449. gc_mark_object (xclosure_frame (object));
  450. gc_mark_object (xclosure_name (object));
  451. object = xclosure_body (object);
  452. break;
  453. case Tstream:
  454. switch (xstream_type (object))
  455. {
  456. case st_file_input:
  457. case st_file_output:
  458. case st_file_io:
  459. object = xfile_stream_pathname (object);
  460. break;
  461. case st_string_input:
  462. case st_string_output:
  463. gc_mark_object (xstring_stream_input (object));
  464. object = xstring_stream_output (object);
  465. break;
  466. case st_synonym:
  467. case st_broadcast:
  468. case st_concatenated:
  469. case st_two_way:
  470. case st_echo:
  471. gc_mark_object (xcomposite_stream_input (object));
  472. object = xcomposite_stream_output (object);
  473. break;
  474. case st_status:
  475. case st_keyboard:
  476. case st_wstream:
  477. case st_socket:
  478. return;
  479. case st_buffer:
  480. gc_mark_object (xbuffer_stream_eob (object));
  481. object = xbuffer_stream_marker (object);
  482. break;
  483. case st_general_input:
  484. gc_mark_object (xgeneral_input_stream_listen_callback (object));
  485. gc_mark_object (xgeneral_input_stream_string (object));
  486. goto general_stream;
  487. case st_general_output:
  488. gc_mark_object (xgeneral_output_stream_flush_callback (object));
  489. goto general_stream;
  490. general_stream:
  491. gc_mark_object (xgeneral_stream_io_callback (object));
  492. object = xgeneral_stream_close_callback (object);
  493. break;
  494. default:
  495. assert (0);
  496. return;
  497. }
  498. break;
  499. case Tpackage:
  500. gc_mark_object (xpackage_name (object));
  501. gc_mark_object (xpackage_nicknames (object));
  502. gc_mark_object (xpackage_use_list (object));
  503. gc_mark_object (xpackage_used_by_list (object));
  504. gc_mark_object (xpackage_shadowings (object));
  505. gc_mark_object (xpackage_external (object));
  506. gc_mark_object (xpackage_documentation (object));
  507. object = xpackage_internal (object);
  508. break;
  509. case Trandom_state:
  510. case Twindow:
  511. case Tbuffer:
  512. case Tsyntax_table:
  513. case Tmarker:
  514. case Terror:
  515. case Twin32_dde_handle:
  516. case Twait_object:
  517. return;
  518. case Toledata:
  519. if (!xoledata_event (object))
  520. return;
  521. object = xoledata_event (object)->handlers ();
  522. break;
  523. case Tprocess:
  524. gc_mark_object (xprocess_buffer (object));
  525. gc_mark_object (xprocess_command (object));
  526. gc_mark_object (xprocess_incode (object));
  527. object = xprocess_outcode (object);
  528. break;
  529. case Tchar_encoding:
  530. gc_mark_object (xchar_encoding_name (object));
  531. object = xchar_encoding_display_name (object);
  532. break;
  533. case Thash_table:
  534. {
  535. hash_entry *e = xhash_table_entry (object);
  536. hash_entry *ee = e + xhash_table_size (object);
  537. for (; e < ee; e++)
  538. {
  539. gc_mark_object (e->key);
  540. gc_mark_object (e->value);
  541. }
  542. object = xhash_table_rehash_size (object);
  543. return;
  544. }
  545. case Tstruct_def:
  546. {
  547. gc_mark_object (xstrdef_name (object));
  548. gc_mark_object (xstrdef_type (object));
  549. gc_mark_object (xstrdef_includes (object));
  550. gc_mark_object (xstrdef_constructors (object));
  551. gc_mark_object (xstrdef_print_function (object));
  552. gc_mark_object (xstrdef_report (object));
  553. for (struct_slotdesc *s = xstrdef_slotdesc (object),
  554. *se = s + xstrdef_nslots (object);
  555. s < se; s++)
  556. {
  557. gc_mark_object (s->name);
  558. gc_mark_object (s->default_init);
  559. gc_mark_object (s->type);
  560. gc_mark_object (s->read_only);
  561. gc_mark_object (s->offset);
  562. }
  563. return;
  564. }
  565. case Tstruct_data:
  566. {
  567. gc_mark_object (xstrdata_def (object));
  568. for (lisp *d = xstrdata_data (object),
  569. *de = d + xstrdata_nslots (object);
  570. d < de; d++)
  571. gc_mark_object (*d);
  572. return;
  573. }
  574. case Treadtable:
  575. {
  576. for (readtab_rep *r = xreadtable_rep (object),
  577. *re = r + READTABLE_REP_SIZE;
  578. r < re; r++)
  579. {
  580. gc_mark_object (r->lfunc);
  581. if (r->disp)
  582. for (disptab_rep *d = r->disp, *de = d + READTABLE_REP_SIZE;
  583. d < de; d++)
  584. gc_mark_object (d->lfunc);
  585. }
  586. return;
  587. }
  588. case Twin32_menu:
  589. gc_mark_object (xwin32_menu_init (object));
  590. gc_mark_object (xwin32_menu_tag (object));
  591. object = xwin32_menu_command (object);
  592. break;
  593. case Tchunk:
  594. gc_mark_object (xchunk_type (object));
  595. object = xchunk_owner (object);
  596. break;
  597. case Tdll_module:
  598. object = xdll_module_name (object);
  599. break;
  600. case Tdll_function:
  601. gc_mark_object (xdll_function_module (object));
  602. object = xdll_function_name (object);
  603. break;
  604. case Tc_callable:
  605. object = xc_callable_function (object);
  606. break;
  607. case Tenvironment:
  608. gc_mark_object (xenvironment_var (object));
  609. gc_mark_object (xenvironment_frame (object));
  610. object = xenvironment_fns (object);
  611. break;
  612. default:
  613. assert (0);
  614. return;
  615. }
  616. }
  617. }
  618. static inline void
  619. gc_mark (lfns *p)
  620. {
  621. for (; p->name; p++)
  622. {
  623. gc_mark_object (*p->sym);
  624. gc_mark_object (p->lfn);
  625. }
  626. }
  627. static inline void
  628. gc_mark (lvars *p)
  629. {
  630. for (; p->name; p++)
  631. gc_mark_object (*p->sym);
  632. }
  633. static inline void
  634. gc_mark (lintr *p)
  635. {
  636. for (; p->s; p++)
  637. gc_mark_object (p->str);
  638. }
  639. static lisp
  640. gc_mark_list (lisp list)
  641. {
  642. lisp ol, nl, cdr;
  643. for (ol = list, nl = Qnil; consp (ol); ol = cdr)
  644. {
  645. cdr = xcdr (ol);
  646. lisp x = xcar (ol);
  647. if (bitisset (gc_place (x), bit_index (x)))
  648. {
  649. bitset (gc_place (ol), bit_index (ol));
  650. xcdr (ol) = nl;
  651. nl = ol;
  652. }
  653. }
  654. return nl;
  655. }
  656. #ifdef DEBUG_GC
  657. static void
  658. shift_funcall_mark (lfns *p)
  659. {
  660. for (; p->name; p++)
  661. p->called = (p->called & 0xc0) | ((p->called << 1) & 0x7f);
  662. }
  663. static void
  664. mark_stack_trace ()
  665. {
  666. for (stack_trace *p = stack_trace::stp; p; p = p->last)
  667. if (p->type != stack_trace::empty)
  668. {
  669. lisp fn = p->fn;
  670. if (symbolp (fn))
  671. fn = xsymbol_function (fn);
  672. if (functionp (fn))
  673. xfunction_tab (fn)->called |= 0x80;
  674. }
  675. }
  676. #endif
  677. void
  678. gc_mark_in_stack ()
  679. {
  680. jmp_buf regs;
  681. setjmp (regs);
  682. int tem = 0;
  683. lisp *beg = (lisp *)&tem, *end = (lisp *)app.initial_stack;
  684. for (; beg < end; beg++)
  685. {
  686. lisp p = *beg;
  687. if (!pointerp (p)
  688. || (char *)p < ldataP::ld_lower_bound
  689. || (char *)p >= ldataP::ld_upper_bound
  690. || (pointer_t (p) & LDATA_PAGE_MASK) < offsetof (ldata_rep, dr_data))
  691. continue;
  692. ldata_rep *r = (ldata_rep *)(pointer_t (p) & ~LDATA_PAGE_MASK);
  693. if (IsBadWritePtr (r, LDATA_PAGE_SIZE))
  694. continue;
  695. int index = bit_index (p);
  696. if (bitisset (r->dr_used, index) && !bitisset (r->dr_gc, index)
  697. && find_object (p))
  698. gc_mark_object (p);
  699. }
  700. }
  701. void
  702. gc_mark_object ()
  703. {
  704. gc_mark_object (Qnil);
  705. gc_mark_object (Qunbound);
  706. gc_mark (lsp_fns);
  707. gc_mark (cl_fns);
  708. gc_mark (sys_fns);
  709. gc_mark (ed_fns);
  710. gc_mark (lsp_vars);
  711. gc_mark (cl_vars);
  712. gc_mark (sys_vars);
  713. gc_mark (kwd_vars);
  714. lisp olist = xsymbol_value (Vdll_module_list); // moduleはあとでやる
  715. xsymbol_value (Vdll_module_list) = Qnil;
  716. gc_mark (unint_vars);
  717. xsymbol_value (Vdll_module_list) = olist;
  718. gc_mark (ed_vars);
  719. gc_mark (intrs);
  720. nonlocal_data *d = nonlocal_jump::data ();
  721. gc_mark_object (d->type);
  722. gc_mark_object (d->value);
  723. gc_mark_object (d->tag);
  724. gc_mark_object (d->id);
  725. {
  726. for (protect_gc *gcp = protect_gc::gcl; gcp; gcp = gcp->last)
  727. for (lisp *p = gcp->var, *pe = p + gcp->nvars; p < pe; p++)
  728. gc_mark_object (*p);
  729. }
  730. {
  731. for (dyn_protect_gc *gcp = dyn_protect_gc::gcl; gcp; gcp = gcp->next)
  732. for (lisp *p = gcp->var, *pe = p + gcp->nvars; p < pe; p++)
  733. gc_mark_object (*p);
  734. }
  735. for (stack_trace *p = stack_trace::stp; p; p = p->last)
  736. if (p->type != stack_trace::empty)
  737. {
  738. gc_mark_object (p->fn);
  739. if (p->args[0])
  740. gc_mark_object (p->args[0]);
  741. if (p->args[1])
  742. gc_mark_object (p->args[1]);
  743. }
  744. for (lex_env *lp = lex_env::le; lp; lp = lp->last)
  745. {
  746. gc_mark_object (lp->lex_var);
  747. gc_mark_object (lp->lex_fns);
  748. gc_mark_object (lp->lex_frame);
  749. }
  750. for (Window *wp = app.active_frame.windows; wp; wp = wp->w_next)
  751. gc_mark_object (wp->lwp);
  752. for (Window *wp = app.active_frame.reserved; wp; wp = wp->w_next)
  753. gc_mark_object (wp->lwp);
  754. for (Window *wp = app.active_frame.deleted; wp; wp = wp->w_next)
  755. gc_mark_object (wp->lwp);
  756. for (Buffer *bp = Buffer::b_blist; bp; bp = bp->b_next)
  757. {
  758. for (lisp *x = &bp->Buffer_gc_start; x <= &bp->Buffer_gc_end; x++)
  759. gc_mark_object (*x);
  760. for (textprop *t = bp->b_textprop; t; t = t->t_next)
  761. gc_mark_object (t->t_tag);
  762. }
  763. toplev_gc_mark (gc_mark_object);
  764. process_gc_mark (gc_mark_object);
  765. g_frame.gc_mark (gc_mark_object);
  766. app.user_timer.gc_mark (gc_mark_object);
  767. gc_mark_in_stack ();
  768. for (Buffer *bp = Buffer::b_blist; bp; bp = bp->b_next)
  769. bp->lmarkers = gc_mark_list (bp->lmarkers);
  770. xsymbol_value (Vdll_module_list) =
  771. gc_mark_list (xsymbol_value (Vdll_module_list));
  772. }
  773. void
  774. gc (int nomsg)
  775. {
  776. if (suppress_gc::gc_suppressed_p ())
  777. return;
  778. app.in_gc = 1;
  779. if (nomsg < 0)
  780. nomsg = xsymbol_value (Vgarbage_collection_messages) == Qnil;
  781. int msglen = 0;
  782. if (!nomsg)
  783. msglen = app.status_window.text (get_message_string (Mgarbage_collecting));
  784. ldataP::ld_nwasted = 0;
  785. gc_mark_object ();
  786. #define DECLARE_LDATA(a, b) ldata <a, b>::sweep ();
  787. #include "dataP.h"
  788. bignum_allocated_bytes = 0;
  789. #ifdef DEBUG_GC
  790. shift_funcall_mark (lsp_fns);
  791. shift_funcall_mark (cl_fns);
  792. shift_funcall_mark (sys_fns);
  793. shift_funcall_mark (ed_fns);
  794. mark_stack_trace ();
  795. #endif
  796. if (!nomsg)
  797. {
  798. if (msglen)
  799. app.status_window.restore ();
  800. else
  801. app.status_window.text (get_message_string (Mgarbage_collecting_done));
  802. }
  803. _heapmin ();
  804. app.in_gc = 0;
  805. }
  806. lisp
  807. Fgc (lisp nomsg)
  808. {
  809. gc (nomsg && nomsg != Qnil);
  810. #if 0
  811. int i = 1;
  812. #define DECLARE_LDATA(a, b) \
  813. multiple_value::value (i++) = ldata <a, b>::countof ();
  814. #include "dataP.h"
  815. multiple_value::value (0) = Qnil;
  816. multiple_value::count () = i;
  817. #endif
  818. return Qnil;
  819. }
  820. lisp
  821. interactive_string (lisp p)
  822. {
  823. int n = xfunction_interactive (p);
  824. if (!n)
  825. return 0;
  826. return intrs[n - 1].str;
  827. }
  828. void
  829. destruct_string (lisp string)
  830. {
  831. assert (stringp (string));
  832. if (simple_string_p (string))
  833. ldata <lsimple_string, Tsimple_string>::unuse ((lsimple_string *)string);
  834. }
  835. void
  836. destruct_regexp (lisp regexp)
  837. {
  838. assert (regexpp (regexp));
  839. ldata <lregexp, Tregexp>::unuse ((lregexp *)regexp);
  840. }
  841. int ldataP::ld_nwasted;
  842. char *ldataP::ld_upper_bound;
  843. char *ldataP::ld_lower_bound;
  844. #define DECLARE_LDATA(a, b) \
  845. ldataP ldata <a, b>::l_ld; \
  846. int ldata <a, b>::l_nuses; \
  847. int ldata <a, b>::l_nfrees;
  848. #include "dataP.h"
  849. static void
  850. init_syms (lvars *v, lfns *f, lisp pkg, int self_bind)
  851. {
  852. lisp *vec = xvector_contents (xpackage_external (pkg));
  853. int hashsize = xvector_length (xpackage_external (pkg));
  854. for (; v->name; v++)
  855. {
  856. lsymbol *symbol = make_symbol (make_string_simple (v->name, v->size),
  857. v->flags);
  858. *v->sym = symbol;
  859. u_int hash = hashpjw (xsymbol_name (symbol), hashsize);
  860. vec[hash] = xcons (symbol, vec[hash]);
  861. if (lambda_key_p (symbol) || self_bind)
  862. symbol->value = symbol;
  863. else if (specialp (symbol))
  864. symbol->value = Qnil;
  865. symbol->package = pkg;
  866. }
  867. if (f)
  868. for (; f->name; f++)
  869. {
  870. lsymbol *symbol = make_symbol (make_string_simple (f->name, f->size));
  871. *f->sym = symbol;
  872. u_int hash = hashpjw (xsymbol_name (symbol), hashsize);
  873. vec[hash] = xcons (symbol, vec[hash]);
  874. f->lfn = make_function (f->fn, symbol->name, f->flags,
  875. f->nargs, f->nopts, f->interactive);
  876. #ifdef DEBUG_GC
  877. xfunction_tab (f->lfn) = f;
  878. #endif
  879. symbol->fn = f->lfn;
  880. symbol->package = pkg;
  881. }
  882. }
  883. static void
  884. init_default_nonlocal_data ()
  885. {
  886. default_nonlocal_data.type = Qnil;
  887. default_nonlocal_data.value = Qnil;
  888. default_nonlocal_data.tag = Qnil;
  889. default_nonlocal_data.id = Qnil;
  890. }
  891. #define SIMPLE_STRING(NAME) make_string_simple (NAME, sizeof NAME - 1)
  892. #define LISP_INTSIZE 101
  893. #define LISP_EXTSIZE 331
  894. #define CL_INTSIZE 101
  895. #define CL_EXTSIZE 331
  896. #define SYS_INTSIZE 101
  897. #define SYS_EXTSIZE 101
  898. #define KWD_INTSIZE 11
  899. #define KWD_EXTSIZE 331
  900. #define USR_INTSIZE 331
  901. #define USR_EXTSIZE 211
  902. #define CL_USR_INTSIZE 331
  903. #define CL_USR_EXTSIZE 211
  904. #define ED_INTSIZE 211
  905. #define ED_EXTSIZE 331
  906. void
  907. init_syms ()
  908. {
  909. Qnil = make_symbol (SIMPLE_STRING ("nil"), SFconstant);
  910. Qunbound = make_symbol (SIMPLE_STRING ("unbound"));
  911. xsymbol_function (Qnil) = Qunbound;
  912. xsymbol_value (Qnil) = Qnil;
  913. xsymbol_plist (Qnil) = Qnil;
  914. xsymbol_package (Qnil) = Qnil;
  915. xsymbol_function (Qunbound) = Qunbound;
  916. xsymbol_value (Qunbound) = Qunbound;
  917. for (lintr *li = intrs; li->s; li++)
  918. if (*li->s)
  919. li->str = make_string (li->s);
  920. else
  921. li->str = Qnil;
  922. lisp lsp = make_package (SIMPLE_STRING ("lisp"), Qnil,
  923. LISP_INTSIZE, LISP_EXTSIZE);
  924. lisp cl = make_package (SIMPLE_STRING ("common-lisp"),
  925. make_list (SIMPLE_STRING ("cl"), 0),
  926. CL_INTSIZE, CL_EXTSIZE);
  927. lisp sys = make_package (SIMPLE_STRING ("system"),
  928. make_list (SIMPLE_STRING ("si"),
  929. SIMPLE_STRING ("sys"),
  930. 0),
  931. SYS_INTSIZE, SYS_EXTSIZE);
  932. lisp kwd = make_package (SIMPLE_STRING ("keyword"), Qnil,
  933. KWD_INTSIZE, KWD_EXTSIZE);
  934. lisp usr = make_package (SIMPLE_STRING ("user"), Qnil,
  935. USR_INTSIZE, USR_EXTSIZE);
  936. lisp cl_usr = make_package (SIMPLE_STRING ("common-lisp-user"),
  937. make_list (SIMPLE_STRING ("cl-user"), 0),
  938. CL_USR_INTSIZE, CL_USR_EXTSIZE);
  939. lisp ed = make_package (SIMPLE_STRING ("editor"),
  940. xcons (SIMPLE_STRING ("ed"), Qnil),
  941. ED_INTSIZE, ED_EXTSIZE);
  942. xsymbol_package (Qnil) = lsp;
  943. xpackage_use_list (sys) = xcons (lsp, Qnil);
  944. xpackage_use_list (ed) = xcons (lsp, Qnil);
  945. xpackage_use_list (usr) = make_list (lsp, ed, 0);
  946. xpackage_use_list (cl) = make_list (lsp, 0);
  947. xpackage_use_list (cl_usr) = make_list (cl, ed, 0);
  948. xpackage_used_by_list (lsp) = make_list (sys, ed, usr, cl, 0);
  949. xpackage_used_by_list (cl) = make_list (cl_usr, 0);
  950. xpackage_used_by_list (ed) = make_list (cl_usr, usr, 0);
  951. u_int hash = hashpjw (xsymbol_name (Qnil), LISP_EXTSIZE);
  952. lisp *vec = xvector_contents (xpackage_external (lsp));
  953. vec[hash] = xcons (Qnil, vec[hash]);
  954. init_syms (lsp_vars, lsp_fns, lsp, 0);
  955. init_syms (cl_vars, cl_fns, cl, 0);
  956. init_syms (sys_vars, sys_fns, sys, 0);
  957. init_syms (kwd_vars, 0, kwd, 1);
  958. init_syms (ed_vars, ed_fns, ed, 0);
  959. lisp name = make_string_simple ("", 0);
  960. for (lvars *v = unint_vars; v->name; v++)
  961. {
  962. lsymbol *symbol = make_symbol (name, v->flags);
  963. *v->sym = symbol;
  964. }
  965. xsymbol_value (Vlisp_package) = lsp;
  966. xsymbol_value (Vcommon_lisp_package) = cl;
  967. xsymbol_value (Vsystem_package) = sys;
  968. xsymbol_value (Vkeyword_package) = kwd;
  969. xsymbol_value (Vuser_package) = usr;
  970. xsymbol_value (Vcommon_lisp_user_package) = cl_usr;
  971. xsymbol_value (Veditor_package) = ed;
  972. xsymbol_value (Vpackage_list) = make_list (lsp, sys, kwd, usr, ed, cl, cl_usr, 0);
  973. xsymbol_value (Vpackage) = usr;
  974. multiple_value::value (0) = Qnil;
  975. multiple_value::count () = 1;
  976. init_default_nonlocal_data ();
  977. }
  978. template <class T, u_int F>
  979. class ldata_iter
  980. {
  981. T *i_d, *i_de;
  982. ldata_rep **i_rep;
  983. #ifdef DEBUG
  984. ldata_rep **i_rep0;
  985. #endif
  986. public:
  987. ldata_iter (ldata_rep **, int);
  988. T *next ();
  989. };
  990. template <class T, u_int F>
  991. ldata_iter <T, F>::ldata_iter (ldata_rep **r, int n)
  992. {
  993. #ifdef DEBUG
  994. i_rep0 = r;
  995. #endif
  996. i_rep = r + n;
  997. i_d = i_de = 0;
  998. }
  999. template <class T, u_int F>
  1000. T *
  1001. ldata_iter <T, F>::next ()
  1002. {
  1003. if (i_d == i_de)
  1004. {
  1005. assert (i_rep > i_rep0);
  1006. i_rep--;
  1007. i_d = (T *)(*i_rep)->dr_data;
  1008. i_de = i_d + LDATA_NOBJS (T);
  1009. }
  1010. assert (bitisset ((*i_rep)->dr_used, bit_index (i_d)));
  1011. return i_d++;
  1012. }
  1013. static void
  1014. combine_syms (lvars *v, lfns *f,
  1015. ldata_iter <lsymbol, Tsymbol> &syms,
  1016. ldata_iter <lfunction, Tfunction> &fns)
  1017. {
  1018. for (; v->name; v++)
  1019. *v->sym = syms.next ();
  1020. if (f)
  1021. for (; f->name; f++)
  1022. {
  1023. *f->sym = syms.next ();
  1024. f->lfn = fns.next ();
  1025. xfunction_fn (f->lfn) = f->fn;
  1026. #ifdef DEBUG_GC
  1027. xfunction_tab (f->lfn) = f;
  1028. #endif
  1029. }
  1030. }
  1031. void
  1032. combine_syms ()
  1033. {
  1034. int n = ldata <lsymbol, Tsymbol>::count_reps ();
  1035. ldata_rep **r = (ldata_rep **)alloca (sizeof *r * n);
  1036. ldata <lsymbol, Tsymbol>::get_reps (r);
  1037. ldata_iter <lsymbol, Tsymbol> syms (r, n);
  1038. n = ldata <lfunction, Tfunction>::count_reps ();
  1039. r = (ldata_rep **)alloca (sizeof *r * n);
  1040. ldata <lfunction, Tfunction>::get_reps (r);
  1041. ldata_iter <lfunction, Tfunction> fns (r, n);
  1042. n = ldata <lsimple_string, Tsimple_string>::count_reps ();
  1043. r = (ldata_rep **)alloca (sizeof *r * n);
  1044. ldata <lsimple_string, Tsimple_string>::get_reps (r);
  1045. ldata_iter <lsimple_string, Tsimple_string> strs (r, n);
  1046. Qnil = syms.next ();
  1047. Qunbound = syms.next ();
  1048. strs.next ();
  1049. strs.next ();
  1050. for (lintr *li = intrs; li->s; li++)
  1051. if (*li->s)
  1052. li->str = strs.next ();
  1053. else
  1054. li->str = Qnil;
  1055. combine_syms (lsp_vars, lsp_fns, syms, fns);
  1056. combine_syms (cl_vars, cl_fns, syms, fns);
  1057. combine_syms (sys_vars, sys_fns, syms, fns);
  1058. combine_syms (kwd_vars, 0, syms, fns);
  1059. combine_syms (ed_vars, ed_fns, syms, fns);
  1060. combine_syms (unint_vars, 0, syms, fns);
  1061. multiple_value::value (0) = Qnil;
  1062. multiple_value::count () = 1;
  1063. init_default_nonlocal_data ();
  1064. }
  1065. #define DECLARE_LDATA_BEGIN static const int ldata_begin = __LINE__;
  1066. #define DECLARE_LDATA_END static const int ldata_end = __LINE__;
  1067. #define DECLARE_LDATA(a, b)
  1068. #include "dataP.h"
  1069. static const int nobject_type = ldata_end - ldata_begin - 1;
  1070. struct dump_header
  1071. {
  1072. long magic;
  1073. long version;
  1074. long file_size;
  1075. long file_size_not;
  1076. int nobject_type;
  1077. int nreps;
  1078. lisp nil;
  1079. };
  1080. struct addr_order
  1081. {
  1082. int i;
  1083. ldata_rep *p;
  1084. };
  1085. class dump_error
  1086. {
  1087. public:
  1088. dump_error (){}
  1089. };
  1090. static addr_order *addr_orderp;
  1091. static int nreps;
  1092. static ldata_rep **laddrp;
  1093. static int __cdecl
  1094. search_addr (const void *p1, const void *p2)
  1095. {
  1096. const char *x = (const char *)p1;
  1097. const char *y = (const char *)((const addr_order *)p2)->p;
  1098. if (x == y)
  1099. return 0;
  1100. return x < y ? -1 : 1;
  1101. }
  1102. static lisp
  1103. lmap (lisp p)
  1104. {
  1105. if (immediatep (p))
  1106. return p;
  1107. addr_order *ap = (addr_order *)bsearch (lisp (pointer_t (p) & ~LDATA_PAGE_MASK), addr_orderp,
  1108. nreps, sizeof *addr_orderp, search_addr);
  1109. assert (ap);
  1110. return lisp (u_long (ap->i) + (pointer_t (p) & LDATA_PAGE_MASK));
  1111. }
  1112. static inline lisp
  1113. rlmap (lisp p)
  1114. {
  1115. if (immediatep (p))
  1116. return p;
  1117. assert (pointer_t (p) / LDATA_PAGE_SIZE < pointer_t (nreps));
  1118. return lisp ((char *)laddrp[pointer_t (p) / LDATA_PAGE_SIZE]
  1119. + (pointer_t (p) & LDATA_PAGE_MASK));
  1120. }
  1121. static int __cdecl
  1122. compare_addr (const void *p1, const void *p2)
  1123. {
  1124. const char *x = (const char *)((const addr_order *)p1)->p;
  1125. const char *y = (const char *)((const addr_order *)p2)->p;
  1126. assert (x != y);
  1127. return x < y ? -1 : 1;
  1128. }
  1129. static void
  1130. writef (FILE *fp, const void *p, size_t size)
  1131. {
  1132. if (size && fwrite (p, size, 1, fp) != 1)
  1133. {
  1134. int e = errno;
  1135. fclose (fp);
  1136. FEsimple_crtl_error (e);
  1137. }
  1138. }
  1139. static inline void
  1140. writef (FILE *fp, lisp x)
  1141. {
  1142. x = lmap (x);
  1143. writef (fp, &x, sizeof x);
  1144. }
  1145. static inline void
  1146. readf (FILE *fp, void *b, size_t size)
  1147. {
  1148. if (size && fread (b, size, 1, fp) != 1)
  1149. throw dump_error ();
  1150. }
  1151. static inline lisp
  1152. readl (FILE *fp)
  1153. {
  1154. lisp x;
  1155. readf (fp, &x, sizeof x);
  1156. return rlmap (x);
  1157. }
  1158. static void
  1159. dump_object (FILE *fp, const lcons *d, int n,
  1160. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1161. {
  1162. for (const lcons *de = d + n; d < de; d++)
  1163. if (bitisset (used, bit_index (d)))
  1164. {
  1165. writef (fp, d->car);
  1166. writef (fp, d->cdr);
  1167. }
  1168. }
  1169. static void
  1170. rdump_object (FILE *fp, lcons *d, int n,
  1171. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1172. {
  1173. for (lcons *de = d + n; d < de; d++)
  1174. if (bitisset (used, bit_index (d)))
  1175. {
  1176. d->car = readl (fp);
  1177. d->cdr = readl (fp);
  1178. }
  1179. }
  1180. static void
  1181. dump_object (FILE *fp, const lsymbol *d, int n,
  1182. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1183. {
  1184. for (const lsymbol *de = d + n; d < de; d++)
  1185. if (bitisset (used, bit_index (d)))
  1186. {
  1187. writef (fp, &d->flags, sizeof d->flags);
  1188. writef (fp, d->value);
  1189. writef (fp, d->fn);
  1190. writef (fp, d->plist);
  1191. writef (fp, d->package);
  1192. writef (fp, d->name);
  1193. }
  1194. }
  1195. static void
  1196. rdump_object (FILE *fp, lsymbol *d, int n,
  1197. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1198. {
  1199. for (lsymbol *de = d + n; d < de; d++)
  1200. if (bitisset (used, bit_index (d)))
  1201. {
  1202. readf (fp, &d->flags, sizeof d->flags);
  1203. d->value = readl (fp);
  1204. d->fn = readl (fp);
  1205. d->plist = readl (fp);
  1206. d->package = readl (fp);
  1207. d->name = readl (fp);
  1208. }
  1209. }
  1210. template <class T>
  1211. void
  1212. dump_simple (FILE *fp, T *d, int n, const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1213. {
  1214. for (T *de = d + n; d < de; d++)
  1215. if (bitisset (used, bit_index (d)))
  1216. writef (fp, (const void *)d, sizeof *d);
  1217. }
  1218. template <class T>
  1219. void
  1220. rdump_simple (FILE *fp, T *d, int n, const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1221. {
  1222. for (T *de = d + n; d < de; d++)
  1223. if (bitisset (used, bit_index (d)))
  1224. readf (fp, (void *)d, sizeof *d);
  1225. }
  1226. static inline void
  1227. dump_object (FILE *fp, const llong_int *d, int n,
  1228. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1229. {
  1230. dump_simple (fp, d, n, used);
  1231. }
  1232. static inline void
  1233. rdump_object (FILE *fp, llong_int *d, int n,
  1234. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1235. {
  1236. rdump_simple (fp, d, n, used);
  1237. }
  1238. static void
  1239. dump_object (FILE *fp, const lfraction *d, int n,
  1240. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1241. {
  1242. for (const lfraction *de = d + n; d < de; d++)
  1243. if (bitisset (used, bit_index (d)))
  1244. {
  1245. writef (fp, d->num);
  1246. writef (fp, d->den);
  1247. }
  1248. }
  1249. static void
  1250. rdump_object (FILE *fp, lfraction *d, int n,
  1251. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1252. {
  1253. for (lfraction *de = d + n; d < de; d++)
  1254. if (bitisset (used, bit_index (d)))
  1255. {
  1256. d->num = readl (fp);
  1257. d->den = readl (fp);
  1258. }
  1259. }
  1260. static void
  1261. dump_object (FILE *fp, const lbignum *d, int n,
  1262. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1263. {
  1264. for (const lbignum *de = d + n; d < de; d++)
  1265. if (bitisset (used, bit_index (d)))
  1266. writef (fp, d->rep,
  1267. (d->rep->br_len
  1268. ? sizeof *d->rep + (d->rep->br_len - 1) * sizeof *d->rep->br_data
  1269. : sizeof *d->rep));
  1270. }
  1271. static void
  1272. rdump_object (FILE *fp, lbignum *d, int n,
  1273. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1274. {
  1275. for (lbignum *de = d + n; d < de; d++)
  1276. if (bitisset (used, bit_index (d)))
  1277. {
  1278. bignum_rep r;
  1279. readf (fp, &r, sizeof r);
  1280. if (r.zerop ())
  1281. d->rep = &bignum_rep_zero;
  1282. else if (r.br_len == 1 && r.br_data[0] == 1)
  1283. d->rep = r.plusp () ? &bignum_rep_one : &bignum_rep_minus_one;
  1284. else
  1285. {
  1286. d->rep = br_new (r.br_len);
  1287. d->rep->br_sign = r.br_sign;
  1288. d->rep->br_data[0] = r.br_data[0];
  1289. readf (fp, &d->rep->br_data[1],
  1290. (r.br_len - 1) * sizeof *d->rep->br_data);
  1291. }
  1292. }
  1293. }
  1294. static inline void
  1295. dump_object (FILE *fp, const lsingle_float *d, int n,
  1296. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1297. {
  1298. dump_simple (fp, d, n, used);
  1299. }
  1300. static inline void
  1301. rdump_object (FILE *fp, lsingle_float *d, int n,
  1302. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1303. {
  1304. rdump_simple (fp, d, n, used);
  1305. }
  1306. static inline void
  1307. dump_object (FILE *fp, const ldouble_float *d, int n,
  1308. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1309. {
  1310. dump_simple (fp, d, n, used);
  1311. }
  1312. static inline void
  1313. rdump_object (FILE *fp, ldouble_float *d, int n,
  1314. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1315. {
  1316. rdump_simple (fp, d, n, used);
  1317. }
  1318. static void
  1319. dump_object (FILE *fp, const lcomplex *d, int n,
  1320. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1321. {
  1322. for (const lcomplex *de = d + n; d < de; d++)
  1323. if (bitisset (used, bit_index (d)))
  1324. {
  1325. writef (fp, d->real);
  1326. writef (fp, d->imag);
  1327. }
  1328. }
  1329. static void
  1330. rdump_object (FILE *fp, lcomplex *d, int n,
  1331. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1332. {
  1333. for (lcomplex *de = d + n; d < de; d++)
  1334. if (bitisset (used, bit_index (d)))
  1335. {
  1336. d->real = readl (fp);
  1337. d->imag = readl (fp);
  1338. }
  1339. }
  1340. static void
  1341. dump_object (FILE *fp, const lclosure *d, int n,
  1342. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1343. {
  1344. for (const lclosure *de = d + n; d < de; d++)
  1345. if (bitisset (used, bit_index (d)))
  1346. {
  1347. writef (fp, d->body);
  1348. writef (fp, d->vars);
  1349. writef (fp, d->fns);
  1350. writef (fp, d->frame);
  1351. writef (fp, d->name);
  1352. }
  1353. }
  1354. static void
  1355. rdump_object (FILE *fp, lclosure *d, int n,
  1356. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1357. {
  1358. for (lclosure *de = d + n; d < de; d++)
  1359. if (bitisset (used, bit_index (d)))
  1360. {
  1361. d->body = readl (fp);
  1362. d->vars = readl (fp);
  1363. d->fns = readl (fp);
  1364. d->frame = readl (fp);
  1365. d->name = readl (fp);
  1366. }
  1367. }
  1368. static void
  1369. dump_vector_contents (FILE *fp, lisp *p, int l)
  1370. {
  1371. for (lisp *pe = p + l; p < pe; p++)
  1372. writef (fp, *p);
  1373. }
  1374. static void *
  1375. rdump_vector_contents (FILE *fp, int l)
  1376. {
  1377. void *p0 = xmalloc (sizeof (lisp) * l);
  1378. readf (fp, p0, sizeof (lisp) * l);
  1379. for (lisp *p = (lisp *)p0, *pe = p + l; p < pe; p++)
  1380. *p = rlmap (*p);
  1381. return p0;
  1382. }
  1383. static void
  1384. dump_displaced_offset (FILE *fp, const lbase_array *d)
  1385. {
  1386. lbase_vector *b = (lbase_vector *)d->displaced_to;
  1387. ptrdiff_t diff = (char *)d->contents - (char *)b->contents;
  1388. writef (fp, &diff, sizeof diff);
  1389. }
  1390. static void
  1391. rdump_displaced_offset (FILE *fp, lbase_array *d)
  1392. {
  1393. ptrdiff_t diff;
  1394. readf (fp, &diff, sizeof diff);
  1395. d->contents = (void *)((diff << 1) | 1);
  1396. }
  1397. static void
  1398. fixup_displaced_offset (lbase_array *d)
  1399. {
  1400. if (!(ptrdiff_t (d->contents) & 1))
  1401. return;
  1402. fixup_displaced_offset ((lbase_array *)d->displaced_to);
  1403. d->contents = (void *)((char *)((lbase_vector *)d->displaced_to)->contents
  1404. + (ptrdiff_t (d->contents) >> 1));
  1405. }
  1406. template <class T, u_int F>
  1407. void
  1408. ldata <T, F>::array_fixup_displaced_offset ()
  1409. {
  1410. for (ldata_rep *lp = l_ld.ld_rep; lp; lp = lp->dr_next)
  1411. for (T *d = (T *)lp->dr_data, *de = d + LDATA_NOBJS (T); d < de; d++)
  1412. if (bitisset (lp->dr_used, bit_index (d)))
  1413. fixup_displaced_offset (d);
  1414. }
  1415. static void
  1416. dump_object (FILE *fp, const lsimple_vector *d, int n,
  1417. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1418. {
  1419. for (const lsimple_vector *de = d + n; d < de; d++)
  1420. if (bitisset (used, bit_index (d)))
  1421. {
  1422. writef (fp, &d->length, sizeof d->length);
  1423. dump_vector_contents (fp, (lisp *)d->contents, d->length);
  1424. }
  1425. }
  1426. static void
  1427. rdump_object (FILE *fp, lsimple_vector *d, int n,
  1428. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1429. {
  1430. for (lsimple_vector *de = d + n; d < de; d++)
  1431. if (bitisset (used, bit_index (d)))
  1432. {
  1433. readf (fp, &d->length, sizeof d->length);
  1434. d->contents = rdump_vector_contents (fp, d->length);
  1435. }
  1436. }
  1437. static void
  1438. dump_object (FILE *fp, const lcomplex_vector *d, int n,
  1439. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1440. {
  1441. for (const lcomplex_vector *de = d + n; d < de; d++)
  1442. if (bitisset (used, bit_index (d)))
  1443. {
  1444. writef (fp, &d->length, sizeof d->length);
  1445. writef (fp, d->displaced_to);
  1446. writef (fp, d->referenced_list);
  1447. writef (fp, &d->adjustable, sizeof d->adjustable);
  1448. writef (fp, &d->has_fillp, sizeof d->has_fillp);
  1449. writef (fp, &d->dimension, sizeof d->dimension);
  1450. if (d->displaced_to == Qnil)
  1451. dump_vector_contents (fp, (lisp *)d->contents, d->dimension);
  1452. else
  1453. dump_displaced_offset (fp, d);
  1454. }
  1455. }
  1456. static void
  1457. rdump_object (FILE *fp, lcomplex_vector *d, int n,
  1458. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1459. {
  1460. for (lcomplex_vector *de = d + n; d < de; d++)
  1461. if (bitisset (used, bit_index (d)))
  1462. {
  1463. readf (fp, &d->length, sizeof d->length);
  1464. d->displaced_to = readl (fp);
  1465. d->referenced_list = readl (fp);
  1466. readf (fp, &d->adjustable, sizeof d->adjustable);
  1467. readf (fp, &d->has_fillp, sizeof d->has_fillp);
  1468. readf (fp, &d->dimension, sizeof d->dimension);
  1469. if (d->displaced_to == Qnil)
  1470. d->contents = rdump_vector_contents (fp, d->dimension);
  1471. else
  1472. rdump_displaced_offset (fp, d);
  1473. d->rank = 1;
  1474. d->dims = &d->dimension;
  1475. }
  1476. }
  1477. static void
  1478. dump_object (FILE *fp, const lsimple_string *d, int n,
  1479. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1480. {
  1481. for (const lsimple_string *de = d + n; d < de; d++)
  1482. if (bitisset (used, bit_index (d)))
  1483. {
  1484. writef (fp, &d->length, sizeof d->length);
  1485. writef (fp, d->contents, sizeof (Char) * d->length);
  1486. }
  1487. }
  1488. static void
  1489. rdump_object (FILE *fp, lsimple_string *d, int n,
  1490. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1491. {
  1492. for (lsimple_string *de = d + n; d < de; d++)
  1493. if (bitisset (used, bit_index (d)))
  1494. {
  1495. readf (fp, &d->length, sizeof d->length);
  1496. d->contents = xmalloc (sizeof (Char) * d->length);
  1497. readf (fp, d->contents, sizeof (Char) * d->length);
  1498. }
  1499. }
  1500. static void
  1501. dump_object (FILE *fp, const lcomplex_string *d, int n,
  1502. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1503. {
  1504. for (const lcomplex_string *de = d + n; d < de; d++)
  1505. if (bitisset (used, bit_index (d)))
  1506. {
  1507. writef (fp, &d->length, sizeof d->length);
  1508. writef (fp, d->displaced_to);
  1509. writef (fp, d->referenced_list);
  1510. writef (fp, &d->adjustable, sizeof d->adjustable);
  1511. writef (fp, &d->has_fillp, sizeof d->has_fillp);
  1512. writef (fp, &d->dimension, sizeof d->dimension);
  1513. if (d->displaced_to == Qnil)
  1514. writef (fp, d->contents, sizeof (Char) * d->dimension);
  1515. else
  1516. dump_displaced_offset (fp, d);
  1517. }
  1518. }
  1519. static void
  1520. rdump_object (FILE *fp, lcomplex_string *d, int n,
  1521. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1522. {
  1523. for (lcomplex_string *de = d + n; d < de; d++)
  1524. if (bitisset (used, bit_index (d)))
  1525. {
  1526. readf (fp, &d->length, sizeof d->length);
  1527. d->displaced_to = readl (fp);
  1528. d->referenced_list = readl (fp);
  1529. readf (fp, &d->adjustable, sizeof d->adjustable);
  1530. readf (fp, &d->has_fillp, sizeof d->has_fillp);
  1531. readf (fp, &d->dimension, sizeof d->dimension);
  1532. if (d->displaced_to == Qnil)
  1533. {
  1534. d->contents = xmalloc (sizeof (Char) * d->dimension);
  1535. readf (fp, d->contents, sizeof (Char) * d->dimension);
  1536. }
  1537. else
  1538. rdump_displaced_offset (fp, d);
  1539. d->rank = 1;
  1540. d->dims = &d->dimension;
  1541. }
  1542. }
  1543. static void
  1544. dump_object (FILE *fp, const lgeneral_array *d, int n,
  1545. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1546. {
  1547. for (const lgeneral_array *de = d + n; d < de; d++)
  1548. if (bitisset (used, bit_index (d)))
  1549. {
  1550. writef (fp, &d->length, sizeof d->length);
  1551. writef (fp, &d->rank, sizeof d->rank);
  1552. writef (fp, d->dims, sizeof *d->dims * d->rank);
  1553. writef (fp, d->displaced_to);
  1554. writef (fp, d->referenced_list);
  1555. writef (fp, &d->adjustable, sizeof d->adjustable);
  1556. if (d->displaced_to == Qnil)
  1557. dump_vector_contents (fp, (lisp *)d->contents, d->length);
  1558. else
  1559. dump_displaced_offset (fp, d);
  1560. }
  1561. }
  1562. static void
  1563. rdump_object (FILE *fp, lgeneral_array *d, int n,
  1564. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1565. {
  1566. for (lgeneral_array *de = d + n; d < de; d++)
  1567. if (bitisset (used, bit_index (d)))
  1568. {
  1569. readf (fp, &d->length, sizeof d->length);
  1570. readf (fp, &d->rank, sizeof d->rank);
  1571. if (!d->rank)
  1572. d->dims = 0;
  1573. else
  1574. {
  1575. d->dims = (int *)xmalloc (sizeof *d->dims * d->rank);
  1576. readf (fp, d->dims, sizeof *d->dims * d->rank);
  1577. }
  1578. d->displaced_to = readl (fp);
  1579. d->referenced_list = readl (fp);
  1580. readf (fp, &d->adjustable, sizeof d->adjustable);
  1581. d->has_fillp = 0;
  1582. if (d->displaced_to == Qnil)
  1583. d->contents = rdump_vector_contents (fp, d->length);
  1584. else
  1585. rdump_displaced_offset (fp, d);
  1586. }
  1587. }
  1588. static void
  1589. dump_object (FILE *fp, const lstring_array *d, int n,
  1590. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1591. {
  1592. for (const lstring_array *de = d + n; d < de; d++)
  1593. if (bitisset (used, bit_index (d)))
  1594. {
  1595. writef (fp, &d->length, sizeof d->length);
  1596. writef (fp, &d->rank, sizeof d->rank);
  1597. writef (fp, d->dims, sizeof *d->dims * d->rank);
  1598. writef (fp, d->displaced_to);
  1599. writef (fp, d->referenced_list);
  1600. writef (fp, &d->adjustable, sizeof d->adjustable);
  1601. if (d->displaced_to == Qnil)
  1602. writef (fp, d->contents, sizeof (Char) * d->length);
  1603. else
  1604. dump_displaced_offset (fp, d);
  1605. }
  1606. }
  1607. static void
  1608. rdump_object (FILE *fp, lstring_array *d, int n,
  1609. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1610. {
  1611. for (lstring_array *de = d + n; d < de; d++)
  1612. if (bitisset (used, bit_index (d)))
  1613. {
  1614. readf (fp, &d->length, sizeof d->length);
  1615. readf (fp, &d->rank, sizeof d->rank);
  1616. if (!d->rank)
  1617. d->dims = 0;
  1618. else
  1619. {
  1620. d->dims = (int *)xmalloc (sizeof *d->dims * d->rank);
  1621. readf (fp, d->dims, sizeof *d->dims * d->rank);
  1622. }
  1623. d->displaced_to = readl (fp);
  1624. d->referenced_list = readl (fp);
  1625. readf (fp, &d->adjustable, sizeof d->adjustable);
  1626. d->has_fillp = 0;
  1627. if (d->displaced_to == Qnil)
  1628. {
  1629. d->contents = xmalloc (sizeof (Char) * d->length);
  1630. readf (fp, d->contents, sizeof (Char) * d->length);
  1631. }
  1632. else
  1633. rdump_displaced_offset (fp, d);
  1634. }
  1635. }
  1636. static void
  1637. dump_object (FILE *fp, const lstream *d, int n,
  1638. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1639. {
  1640. for (const lstream *de = d + n; d < de; d++)
  1641. if (bitisset (used, bit_index (d)))
  1642. {
  1643. writef (fp, &d->type, sizeof d->type);
  1644. switch (d->type)
  1645. {
  1646. case st_file_input:
  1647. case st_file_output:
  1648. case st_file_io:
  1649. writef (fp, lisp (d->pathname));
  1650. break;
  1651. case st_string_input:
  1652. case st_string_output:
  1653. case st_synonym:
  1654. case st_broadcast:
  1655. case st_concatenated:
  1656. case st_two_way:
  1657. case st_echo:
  1658. writef (fp, lisp (d->input));
  1659. writef (fp, lisp (d->output));
  1660. break;
  1661. case st_status:
  1662. case st_keyboard:
  1663. case st_wstream:
  1664. case st_socket:
  1665. break;
  1666. case st_buffer:
  1667. writef (fp, lisp (d->input));
  1668. writef (fp, lisp (d->output));
  1669. break;
  1670. case st_general_input:
  1671. writef (fp, lisp (d->input));
  1672. writef (fp, lisp (d->output));
  1673. writef (fp, lisp (d->pathname));
  1674. break;
  1675. case st_general_output:
  1676. writef (fp, lisp (d->input));
  1677. writef (fp, lisp (d->output));
  1678. writef (fp, lisp (d->pathname));
  1679. break;
  1680. default:
  1681. assert (0);
  1682. break;
  1683. }
  1684. }
  1685. }
  1686. static void
  1687. rdump_object (FILE *fp, lstream *d, int n,
  1688. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1689. {
  1690. for (lstream *de = d + n; d < de; d++)
  1691. if (bitisset (used, bit_index (d)))
  1692. {
  1693. d->pending = lChar_EOF;
  1694. d->column = 0;
  1695. d->linenum = 1;
  1696. d->start = 0;
  1697. d->end = 0;
  1698. d->alt_pathname = 0;
  1699. d->open_p = 0;
  1700. d->encoding = lstream::ENCODE_CANON;
  1701. readf (fp, &d->type, sizeof d->type);
  1702. switch (d->type)
  1703. {
  1704. case st_file_input:
  1705. case st_file_output:
  1706. case st_file_io:
  1707. d->pathname = readl (fp);
  1708. d->input = 0;
  1709. d->output = 0;
  1710. break;
  1711. case st_string_input:
  1712. case st_string_output:
  1713. case st_synonym:
  1714. case st_broadcast:
  1715. case st_concatenated:
  1716. case st_two_way:
  1717. case st_echo:
  1718. d->pathname = Qnil;
  1719. d->input = (void *)readl (fp);
  1720. d->output = (void *)readl (fp);
  1721. break;
  1722. case st_status:
  1723. case st_keyboard:
  1724. case st_wstream:
  1725. case st_socket:
  1726. d->pathname = Qnil;
  1727. d->input = 0;
  1728. d->output = 0;
  1729. break;
  1730. case st_buffer:
  1731. d->pathname = Qnil;
  1732. d->input = (void *)readl (fp);
  1733. d->output = (void *)readl (fp);
  1734. break;
  1735. case st_general_input:
  1736. d->input = (void *)readl (fp);
  1737. d->output = (void *)readl (fp);
  1738. d->pathname = readl (fp);
  1739. d->alt_pathname = (char *)Qnil;
  1740. d->start = 0;
  1741. break;
  1742. case st_general_output:
  1743. d->input = (void *)readl (fp);
  1744. d->output = (void *)readl (fp);
  1745. d->pathname = readl (fp);
  1746. break;
  1747. default:
  1748. assert (0);
  1749. break;
  1750. }
  1751. }
  1752. }
  1753. static void
  1754. dump_object (FILE *fp, const lpackage *d, int n,
  1755. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1756. {
  1757. for (const lpackage *de = d + n; d < de; d++)
  1758. if (bitisset (used, bit_index (d)))
  1759. {
  1760. writef (fp, d->name);
  1761. writef (fp, d->nicknames);
  1762. writef (fp, d->use_list);
  1763. writef (fp, d->used_by_list);
  1764. writef (fp, d->shadowings);
  1765. writef (fp, d->internal);
  1766. writef (fp, d->external);
  1767. }
  1768. }
  1769. static void
  1770. rdump_object (FILE *fp, lpackage *d, int n,
  1771. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1772. {
  1773. for (lpackage *de = d + n; d < de; d++)
  1774. if (bitisset (used, bit_index (d)))
  1775. {
  1776. d->name = readl (fp);
  1777. d->nicknames = readl (fp);
  1778. d->use_list = readl (fp);
  1779. d->used_by_list = readl (fp);
  1780. d->shadowings = readl (fp);
  1781. d->internal = readl (fp);
  1782. d->external = readl (fp);
  1783. }
  1784. }
  1785. static void
  1786. dump_object (FILE *fp, const lfunction *d, int n,
  1787. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1788. {
  1789. for (const lfunction *de = d + n; d < de; d++)
  1790. if (bitisset (used, bit_index (d)))
  1791. {
  1792. writef (fp, d->name);
  1793. writef (fp, &d->flags, sizeof d->flags);
  1794. writef (fp, &d->nargs, sizeof d->nargs);
  1795. writef (fp, &d->nopts, sizeof d->nopts);
  1796. writef (fp, &d->interactive, sizeof d->interactive);
  1797. }
  1798. }
  1799. static void
  1800. rdump_object (FILE *fp, lfunction *d, int n,
  1801. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1802. {
  1803. for (lfunction *de = d + n; d < de; d++)
  1804. if (bitisset (used, bit_index (d)))
  1805. {
  1806. d->name = readl (fp);
  1807. readf (fp, &d->flags, sizeof d->flags);
  1808. readf (fp, &d->nargs, sizeof d->nargs);
  1809. readf (fp, &d->nopts, sizeof d->nopts);
  1810. readf (fp, &d->interactive, sizeof d->interactive);
  1811. }
  1812. }
  1813. static void
  1814. dump_object (FILE *fp, const lstruct_def *d, int n,
  1815. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1816. {
  1817. for (const lstruct_def *de = d + n; d < de; d++)
  1818. if (bitisset (used, bit_index (d)))
  1819. {
  1820. writef (fp, d->name);
  1821. writef (fp, d->type);
  1822. writef (fp, d->includes);
  1823. writef (fp, d->constructors);
  1824. writef (fp, d->print_function);
  1825. writef (fp, d->report);
  1826. writef (fp, &d->nslots, sizeof d->nslots);
  1827. dump_vector_contents (fp, (lisp *)d->slotdesc,
  1828. d->nslots * (sizeof *d->slotdesc / sizeof (lisp)));
  1829. writef (fp, &d->named, sizeof d->named);
  1830. writef (fp, &d->read_only, sizeof d->read_only);
  1831. writef (fp, &d->important, sizeof d->important);
  1832. }
  1833. }
  1834. static void
  1835. rdump_object (FILE *fp, lstruct_def *d, int n,
  1836. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1837. {
  1838. for (lstruct_def *de = d + n; d < de; d++)
  1839. if (bitisset (used, bit_index (d)))
  1840. {
  1841. d->name = readl (fp);
  1842. d->type = readl (fp);
  1843. d->includes = readl (fp);
  1844. d->constructors = readl (fp);
  1845. d->print_function = readl (fp);
  1846. d->report = readl (fp);
  1847. readf (fp, &d->nslots, sizeof d->nslots);
  1848. d->slotdesc = (struct_slotdesc *)
  1849. rdump_vector_contents (fp, d->nslots * (sizeof *d->slotdesc / sizeof (lisp)));
  1850. readf (fp, &d->named, sizeof d->named);
  1851. readf (fp, &d->read_only, sizeof d->read_only);
  1852. readf (fp, &d->important, sizeof d->important);
  1853. }
  1854. }
  1855. static void
  1856. dump_object (FILE *fp, const lstruct_data *d, int n,
  1857. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1858. {
  1859. for (const lstruct_data *de = d + n; d < de; d++)
  1860. if (bitisset (used, bit_index (d)))
  1861. {
  1862. writef (fp, d->def);
  1863. writef (fp, &d->nslots, sizeof d->nslots);
  1864. dump_vector_contents (fp, d->data, d->nslots);
  1865. }
  1866. }
  1867. static void
  1868. rdump_object (FILE *fp, lstruct_data *d, int n,
  1869. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1870. {
  1871. for (lstruct_data *de = d + n; d < de; d++)
  1872. if (bitisset (used, bit_index (d)))
  1873. {
  1874. d->def = readl (fp);
  1875. readf (fp, &d->nslots, sizeof d->nslots);
  1876. d->data = (lisp *)rdump_vector_contents (fp, d->nslots);
  1877. }
  1878. }
  1879. static inline void
  1880. dump_object (FILE *, const lwindow *, int,
  1881. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  1882. {
  1883. }
  1884. static void
  1885. rdump_object (FILE *fp, lwindow *d, int n,
  1886. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1887. {
  1888. for (lwindow *de = d + n; d < de; d++)
  1889. if (bitisset (used, bit_index (d)))
  1890. d->wp = 0;
  1891. }
  1892. static inline void
  1893. dump_object (FILE *, const lbuffer *, int,
  1894. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  1895. {
  1896. }
  1897. static void
  1898. rdump_object (FILE *fp, lbuffer *d, int n,
  1899. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1900. {
  1901. for (lbuffer *de = d + n; d < de; d++)
  1902. if (bitisset (used, bit_index (d)))
  1903. d->bp = 0;
  1904. }
  1905. static void
  1906. dump_object (FILE *fp, const lsyntax_table *d, int n,
  1907. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1908. {
  1909. for (const lsyntax_table *de = d + n; d < de; d++)
  1910. if (bitisset (used, bit_index (d)))
  1911. writef (fp, d->table, sizeof *d->table);
  1912. }
  1913. static void
  1914. rdump_object (FILE *fp, lsyntax_table *d, int n,
  1915. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1916. {
  1917. for (lsyntax_table *de = d + n; d < de; d++)
  1918. if (bitisset (used, bit_index (d)))
  1919. {
  1920. d->table = (syntax_table *)xmalloc (sizeof *d->table);
  1921. readf (fp, d->table, sizeof *d->table);
  1922. }
  1923. }
  1924. static inline void
  1925. dump_object (FILE *, const lmarker *, int,
  1926. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  1927. {
  1928. }
  1929. static void
  1930. rdump_object (FILE *fp, lmarker *d, int n,
  1931. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1932. {
  1933. for (lmarker *de = d + n; d < de; d++)
  1934. if (bitisset (used, bit_index (d)))
  1935. d->buffer = 0;
  1936. }
  1937. static inline void
  1938. dump_object (FILE *, const lprocess *, int,
  1939. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  1940. {
  1941. }
  1942. static void
  1943. rdump_object (FILE *fp, lprocess *d, int n,
  1944. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1945. {
  1946. for (lprocess *de = d + n; d < de; d++)
  1947. if (bitisset (used, bit_index (d)))
  1948. {
  1949. d->data = 0;
  1950. d->status = PS_NONE;
  1951. d->buffer = Qnil;
  1952. d->command = Qnil;
  1953. d->incode = Qnil;
  1954. d->outcode = Qnil;
  1955. }
  1956. }
  1957. static void
  1958. dump_object (FILE *fp, const lregexp *d, int n,
  1959. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1960. {
  1961. for (const lregexp *de = d + n; d < de; d++)
  1962. if (bitisset (used, bit_index (d)))
  1963. {
  1964. writef (fp, &d->length, sizeof d->length);
  1965. writef (fp, &d->flags, sizeof d->flags);
  1966. writef (fp, d->pattern, sizeof (Char) * d->length);
  1967. writef (fp, d->source);
  1968. }
  1969. }
  1970. static void
  1971. rdump_object (FILE *fp, lregexp *d, int n,
  1972. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1973. {
  1974. for (lregexp *de = d + n; d < de; d++)
  1975. if (bitisset (used, bit_index (d)))
  1976. {
  1977. readf (fp, &d->length, sizeof d->length);
  1978. readf (fp, &d->flags, sizeof d->flags);
  1979. d->pattern = (Char *)xmalloc (sizeof (Char) * d->length);
  1980. readf (fp, d->pattern, sizeof (Char) * d->length);
  1981. d->source = readl (fp);
  1982. }
  1983. }
  1984. static inline void
  1985. dump_object (FILE *, const lwin32_menu *, int,
  1986. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  1987. {
  1988. }
  1989. static void
  1990. rdump_object (FILE *fp, lwin32_menu *d, int n,
  1991. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  1992. {
  1993. for (lwin32_menu *de = d + n; d < de; d++)
  1994. if (bitisset (used, bit_index (d)))
  1995. {
  1996. d->handle = 0;
  1997. d->id = 0;
  1998. d->init = Qnil;
  1999. d->command = Qnil;
  2000. d->tag = Qnil;
  2001. }
  2002. }
  2003. static inline void
  2004. dump_object (FILE *, const lwin32_dde_handle *, int,
  2005. const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  2006. {
  2007. }
  2008. static void
  2009. rdump_object (FILE *fp, lwin32_dde_handle *d, int n,
  2010. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2011. {
  2012. for (lwin32_dde_handle *de = d + n; d < de; d++)
  2013. if (bitisset (used, bit_index (d)))
  2014. d->hconv = 0;
  2015. }
  2016. #define HT_EQ 0
  2017. #define HT_EQL 1
  2018. #define HT_EQUAL 2
  2019. #define HT_EQUALP 3
  2020. static void
  2021. dump_object (FILE *fp, const lhash_table *d, int n,
  2022. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2023. {
  2024. for (const lhash_table *de = d + n; d < de; d++)
  2025. if (bitisset (used, bit_index (d)))
  2026. {
  2027. int test;
  2028. if (d->test == Feq)
  2029. test = HT_EQ;
  2030. else if (d->test == Feql)
  2031. test = HT_EQL;
  2032. else if (d->test == Fequal)
  2033. test = HT_EQUAL;
  2034. else
  2035. test = HT_EQUALP;
  2036. writef (fp, &test, sizeof test);
  2037. writef (fp, &d->size, sizeof d->size);
  2038. writef (fp, d->rehash_size);
  2039. writef (fp, &d->rehash_threshold, sizeof d->rehash_threshold);
  2040. writef (fp, &d->used, sizeof d->used);
  2041. writef (fp, &d->count, sizeof d->count);
  2042. for (const hash_entry *e = d->entry, *ee = e + d->size; e < ee; e++)
  2043. {
  2044. writef (fp, e->key);
  2045. writef (fp, e->value);
  2046. }
  2047. }
  2048. }
  2049. static void
  2050. rdump_object (FILE *fp, lhash_table *d, int n,
  2051. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2052. {
  2053. for (lhash_table *de = d + n; d < de; d++)
  2054. if (bitisset (used, bit_index (d)))
  2055. {
  2056. int test;
  2057. readf (fp, &test, sizeof test);
  2058. if (test == HT_EQ)
  2059. d->test = Feq;
  2060. else if (test == HT_EQL)
  2061. d->test = Feql;
  2062. else if (test == HT_EQUAL)
  2063. d->test = Fequal;
  2064. else
  2065. d->test = Fequalp;
  2066. readf (fp, &d->size, sizeof d->size);
  2067. d->rehash_size = readl (fp);
  2068. readf (fp, &d->rehash_threshold, sizeof d->rehash_threshold);
  2069. readf (fp, &d->used, sizeof d->used);
  2070. readf (fp, &d->count, sizeof d->count);
  2071. d->entry = (hash_entry *)xmalloc (sizeof *d->entry * d->size);
  2072. readf (fp, d->entry, sizeof *d->entry * d->size);
  2073. for (hash_entry *e = d->entry, *ee = e + d->size; e < ee; e++)
  2074. {
  2075. e->key = rlmap (e->key);
  2076. e->value = rlmap (e->value);
  2077. }
  2078. }
  2079. }
  2080. static void
  2081. dump_object (FILE *fp, const lreadtable *d, int n,
  2082. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2083. {
  2084. for (const lreadtable *de = d + n; d < de; d++)
  2085. if (bitisset (used, bit_index (d)))
  2086. {
  2087. writef (fp, &d->rcase, sizeof d->rcase);
  2088. for (const readtab_rep *r = d->rep, *re = r + READTABLE_REP_SIZE;
  2089. r < re; r++)
  2090. {
  2091. writef (fp, &r->type, sizeof r->type);
  2092. writef (fp, r->lfunc);
  2093. char disp = r->disp ? 1 : 0;
  2094. writef (fp, &disp, sizeof disp);
  2095. if (disp)
  2096. for (const disptab_rep *dr = r->disp, *dre = dr + READTABLE_REP_SIZE;
  2097. dr < dre; dr++)
  2098. writef (fp, dr->lfunc);
  2099. }
  2100. }
  2101. }
  2102. static void
  2103. rdump_object (FILE *fp, lreadtable *d, int n,
  2104. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2105. {
  2106. for (lreadtable *de = d + n; d < de; d++)
  2107. if (bitisset (used, bit_index (d)))
  2108. {
  2109. readf (fp, &d->rcase, sizeof d->rcase);
  2110. d->rep = (readtab_rep *)xmalloc (sizeof (readtab_rep) * READTABLE_REP_SIZE);
  2111. bzero (d->rep, sizeof (readtab_rep) * READTABLE_REP_SIZE);
  2112. for (readtab_rep *r = d->rep, *re = r + READTABLE_REP_SIZE;
  2113. r < re; r++)
  2114. {
  2115. readf (fp, &r->type, sizeof r->type);
  2116. r->lfunc = readl (fp);
  2117. r->cfunc = get_reader_macro_function (r->lfunc);
  2118. char disp;
  2119. readf (fp, &disp, sizeof disp);
  2120. if (disp)
  2121. {
  2122. r->disp = (disptab_rep *)xmalloc (sizeof (disptab_rep) * READTABLE_REP_SIZE);
  2123. for (disptab_rep *dr = r->disp, *dre = dr + READTABLE_REP_SIZE;
  2124. dr < dre; dr++)
  2125. {
  2126. dr->lfunc = readl (fp);
  2127. dr->cfunc = get_reader_dispmacro_function (dr->lfunc);
  2128. }
  2129. }
  2130. }
  2131. }
  2132. }
  2133. static inline void
  2134. dump_object (FILE *fp, const lerror *d, int n,
  2135. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2136. {
  2137. dump_simple (fp, d, n, used);
  2138. }
  2139. static inline void
  2140. rdump_object (FILE *fp, lerror *d, int n,
  2141. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2142. {
  2143. rdump_simple (fp, d, n, used);
  2144. }
  2145. static inline void
  2146. dump_object (FILE *fp, const lrandom_state *d, int n,
  2147. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2148. {
  2149. dump_simple (fp, d, n, used);
  2150. }
  2151. static inline void
  2152. rdump_object (FILE *fp, lrandom_state *d, int n,
  2153. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2154. {
  2155. rdump_simple (fp, d, n, used);
  2156. }
  2157. static void
  2158. dump_object (FILE *fp, const lchunk *d, int n,
  2159. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2160. {
  2161. for (const lchunk *de = d + n; d < de; d++)
  2162. if (bitisset (used, bit_index (d)))
  2163. {
  2164. writef (fp, d->type);
  2165. writef (fp, &d->size, sizeof d->size);
  2166. writef (fp, d->owner);
  2167. if (d->owner == lisp (d))
  2168. writef (fp, d->data, d->size);
  2169. else if (d->owner == Qnil)
  2170. writef (fp, &d->data, sizeof d->data);
  2171. else
  2172. {
  2173. ptrdiff_t diff = (char *)d->data - (char *)xchunk_data (d->owner);
  2174. writef (fp, &diff, sizeof diff);
  2175. }
  2176. }
  2177. assert (sizeof (void *) >= sizeof (ptrdiff_t));
  2178. }
  2179. static void
  2180. rdump_object (FILE *fp, lchunk *d, int n,
  2181. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2182. {
  2183. for (lchunk *de = d + n; d < de; d++)
  2184. if (bitisset (used, bit_index (d)))
  2185. {
  2186. d->type = readl (fp);
  2187. readf (fp, &d->size, sizeof d->size);
  2188. d->owner = readl (fp);
  2189. if (d->owner == d)
  2190. {
  2191. d->data = xmalloc (d->size);
  2192. readf (fp, d->data, d->size);
  2193. }
  2194. else if (d->owner == Qnil)
  2195. readf (fp, &d->data, sizeof d->data);
  2196. else
  2197. {
  2198. ptrdiff_t diff;
  2199. readf (fp, &diff, sizeof diff);
  2200. d->data = (void *)diff;
  2201. }
  2202. }
  2203. }
  2204. static void
  2205. fixup_chunk_offset (lchunk *d)
  2206. {
  2207. if (d->owner == d || d->owner == Qnil)
  2208. return;
  2209. void *p = (void *)((char *)((lchunk *)d->owner)->data
  2210. + ptrdiff_t (d->data));
  2211. if (d->data == p)
  2212. return;
  2213. fixup_chunk_offset ((lchunk *)d->owner);
  2214. d->data = p;
  2215. }
  2216. template <class T, u_int F>
  2217. void
  2218. ldata <T, F>::chunk_fixup_data_offset ()
  2219. {
  2220. for (ldata_rep *lp = l_ld.ld_rep; lp; lp = lp->dr_next)
  2221. for (T *d = (T *)lp->dr_data, *de = d + LDATA_NOBJS (T); d < de; d++)
  2222. if (bitisset (lp->dr_used, bit_index (d)))
  2223. fixup_chunk_offset (d);
  2224. }
  2225. static void
  2226. dump_object (FILE *fp, const ldll_module *d, int n,
  2227. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2228. {
  2229. for (const ldll_module *de = d + n; d < de; d++)
  2230. if (bitisset (used, bit_index (d)))
  2231. writef (fp, d->name);
  2232. }
  2233. static void
  2234. load_dyn_library (ldll_module *p)
  2235. {
  2236. char *s = (char *)alloca (xstring_length (p->name) * 2 + 1);
  2237. w2s (s, p->name);
  2238. p->loaded = 0;
  2239. HMODULE h = GetModuleHandle (s);
  2240. if (!h)
  2241. {
  2242. h = WINFS::LoadLibrary (s);
  2243. if (h)
  2244. p->loaded = 1;
  2245. }
  2246. p->handle = h;
  2247. }
  2248. static void
  2249. rdump_object (FILE *fp, ldll_module *d, int n,
  2250. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2251. {
  2252. for (ldll_module *de = d + n; d < de; d++)
  2253. if (bitisset (used, bit_index (d)))
  2254. {
  2255. d->name = readl (fp);
  2256. load_dyn_library (d);
  2257. }
  2258. }
  2259. static void
  2260. dump_object (FILE *fp, const ldll_function *d, int n,
  2261. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2262. {
  2263. for (const ldll_function *de = d + n; d < de; d++)
  2264. if (bitisset (used, bit_index (d)))
  2265. {
  2266. writef (fp, d->module);
  2267. writef (fp, d->name);
  2268. writef (fp, &d->nargs, sizeof d->nargs);
  2269. writef (fp, d->arg_types, d->nargs);
  2270. writef (fp, &d->arg_size, sizeof d->arg_size);
  2271. writef (fp, &d->return_type, sizeof d->return_type);
  2272. }
  2273. }
  2274. static FARPROC
  2275. load_dyn_function (const ldll_function *d)
  2276. {
  2277. if (!xdll_module_handle (d->module))
  2278. return 0;
  2279. char *s = (char *)alloca (xstring_length (d->name) * 2 + 1);
  2280. w2s (s, d->name);
  2281. return GetProcAddress (xdll_module_handle (d->module), s);
  2282. }
  2283. static void
  2284. rdump_object (FILE *fp, ldll_function *d, int n,
  2285. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2286. {
  2287. for (ldll_function *de = d + n; d < de; d++)
  2288. if (bitisset (used, bit_index (d)))
  2289. {
  2290. d->module = readl (fp);
  2291. d->name = readl (fp);
  2292. readf (fp, &d->nargs, sizeof d->nargs);
  2293. d->arg_types = (u_char *)xmalloc (d->nargs);
  2294. readf (fp, d->arg_types, d->nargs);
  2295. readf (fp, &d->arg_size, sizeof d->arg_size);
  2296. readf (fp, &d->return_type, sizeof d->return_type);
  2297. d->proc = load_dyn_function (d);
  2298. }
  2299. }
  2300. static void
  2301. dump_object (FILE *fp, const lc_callable *d, int n,
  2302. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2303. {
  2304. for (const lc_callable *de = d + n; d < de; d++)
  2305. if (bitisset (used, bit_index (d)))
  2306. {
  2307. writef (fp, d->function);
  2308. writef (fp, &d->nargs, sizeof d->nargs);
  2309. writef (fp, d->arg_types, d->nargs);
  2310. writef (fp, &d->arg_size, sizeof d->arg_size);
  2311. writef (fp, &d->return_type, sizeof d->return_type);
  2312. writef (fp, &d->convention, sizeof d->convention);
  2313. }
  2314. }
  2315. static void
  2316. rdump_object (FILE *fp, lc_callable *d, int n,
  2317. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2318. {
  2319. for (lc_callable *de = d + n; d < de; d++)
  2320. if (bitisset (used, bit_index (d)))
  2321. {
  2322. d->function = readl (fp);
  2323. readf (fp, &d->nargs, sizeof d->nargs);
  2324. d->arg_types = (u_char *)xmalloc (d->nargs);
  2325. readf (fp, d->arg_types, d->nargs);
  2326. readf (fp, &d->arg_size, sizeof d->arg_size);
  2327. readf (fp, &d->return_type, sizeof d->return_type);
  2328. readf (fp, &d->convention, sizeof d->convention);
  2329. init_c_callable (d);
  2330. }
  2331. }
  2332. static inline void
  2333. dump_object (FILE *, const loledata *, int, const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  2334. {
  2335. }
  2336. static void
  2337. rdump_object (FILE *fp, loledata *d, int n, const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2338. {
  2339. for (loledata *de = d + n; d < de; d++)
  2340. if (bitisset (used, bit_index (d)))
  2341. {
  2342. d->disp = 0;
  2343. d->event = 0;
  2344. }
  2345. }
  2346. static inline void
  2347. dump_object (FILE *, const lwait_object *, int, const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  2348. {
  2349. }
  2350. static void
  2351. rdump_object (FILE *fp, lwait_object *d, int n, const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2352. {
  2353. for (lwait_object *de = d + n; d < de; d++)
  2354. if (bitisset (used, bit_index (d)))
  2355. d->hevent = 0;
  2356. }
  2357. static void
  2358. dump_object (FILE *fp, const lchar_encoding *d, int n,
  2359. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2360. {
  2361. for (const lchar_encoding *de = d + n; d < de; d++)
  2362. if (bitisset (used, bit_index (d)))
  2363. {
  2364. writef (fp, &d->type, sizeof d->type);
  2365. writef (fp, d->name);
  2366. writef (fp, d->display_name);
  2367. writef (fp, &d->u, sizeof d->u);
  2368. }
  2369. }
  2370. static void
  2371. rdump_object (FILE *fp, lchar_encoding *d, int n,
  2372. const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2373. {
  2374. for (lchar_encoding *de = d + n; d < de; d++)
  2375. if (bitisset (used, bit_index (d)))
  2376. {
  2377. readf (fp, &d->type, sizeof d->type);
  2378. d->name = readl (fp);
  2379. d->display_name = readl (fp);
  2380. readf (fp, &d->u, sizeof d->u);
  2381. }
  2382. }
  2383. static inline void
  2384. dump_object (FILE *, const lenvironment *, int, const u_long [LDATA_MAX_OBJECTS_PER_LONG])
  2385. {
  2386. }
  2387. static void
  2388. rdump_object (FILE *fp, lenvironment *d, int n, const u_long used[LDATA_MAX_OBJECTS_PER_LONG])
  2389. {
  2390. for (lenvironment *de = d + n; d < de; d++)
  2391. if (bitisset (used, bit_index (d)))
  2392. {
  2393. d->lvar = Qnil;
  2394. d->lframe = Qnil;
  2395. d->lfns = Qnil;
  2396. }
  2397. }
  2398. template <class T, u_int F>
  2399. void
  2400. ldata <T, F>::dump_reps (FILE *fp)
  2401. {
  2402. for (const ldata_rep *lp = l_ld.ld_rep; lp; lp = lp->dr_next)
  2403. {
  2404. writef (fp, lp->dr_used, sizeof lp->dr_used);
  2405. dump_object (fp, (const T *)lp->dr_data, LDATA_NOBJS (T), lp->dr_used);
  2406. }
  2407. }
  2408. #define DMAGIC 0xef1380feL
  2409. extern int dump_version;
  2410. lisp
  2411. Fdump_xyzzy (lisp filename)
  2412. {
  2413. char path_buf[PATH_MAX + 1];
  2414. const char *path;
  2415. if (!filename || filename == Qnil)
  2416. {
  2417. filename = xsymbol_value (Qdump_image_path);
  2418. path = app.dump_image;
  2419. }
  2420. else
  2421. {
  2422. pathname2cstr (filename, path_buf);
  2423. path = path_buf;
  2424. }
  2425. protect_gc gcpro (filename);
  2426. gc (1);
  2427. int i = 0;
  2428. int counts[nobject_type];
  2429. #define DECLARE_LDATA(a, b) counts[i++] = ldata <a, b>::count_reps ();
  2430. #include "dataP.h"
  2431. nreps = 0;
  2432. for (i = 0; i < nobject_type; i++)
  2433. nreps += counts[i];
  2434. ldata_rep **reps = (ldata_rep **)alloca (sizeof *reps * nreps);
  2435. ldata_rep **r = reps;
  2436. i = 0;
  2437. #define DECLARE_LDATA(a, b) ldata <a, b>::get_reps (r); r += counts[i++];
  2438. #include "dataP.h"
  2439. addr_order *ap = (addr_order *)alloca (sizeof *ap * nreps);
  2440. addr_orderp = ap;
  2441. r = reps;
  2442. for (i = 0; i < nreps; i++, r++, ap++)
  2443. {
  2444. ap->i = i * LDATA_PAGE_SIZE;
  2445. ap->p = *r;
  2446. }
  2447. qsort (addr_orderp, nreps, sizeof *addr_orderp, compare_addr);
  2448. FILE *fp = fopen (path, "wb");
  2449. if (!fp)
  2450. FEsimple_crtl_error (errno, filename);
  2451. dump_header head;
  2452. head.magic = DMAGIC;
  2453. head.version = dump_version;
  2454. head.file_size = 0;
  2455. head.file_size_not = 0;
  2456. head.nobject_type = nobject_type;
  2457. head.nreps = nreps;
  2458. head.nil = lmap (Qnil);
  2459. writef (fp, &head, sizeof head);
  2460. writef (fp, counts, sizeof counts);
  2461. #define DECLARE_LDATA(a, b) ldata <a, b>::dump_reps (fp);
  2462. #include "dataP.h"
  2463. long off = ftell (fp);
  2464. head.file_size = off;
  2465. head.file_size_not = ~off;
  2466. fseek (fp, 0, SEEK_SET);
  2467. writef (fp, &head, sizeof head);
  2468. fclose (fp);
  2469. return Qnil;
  2470. }
  2471. template <class T, u_int F>
  2472. void
  2473. ldata <T, F>::rdump_reps (FILE *fp)
  2474. {
  2475. for (ldata_rep *lp = l_ld.ld_rep; lp; lp = lp->dr_next)
  2476. {
  2477. readf (fp, lp->dr_used, sizeof lp->dr_used);
  2478. rdump_object (fp, (T *)lp->dr_data, LDATA_NOBJS (T), lp->dr_used);
  2479. }
  2480. }
  2481. static int
  2482. rdump_xyzzy (FILE *fp)
  2483. {
  2484. dump_header head;
  2485. readf (fp, &head, sizeof head);
  2486. if (head.magic != DMAGIC
  2487. || head.version != dump_version
  2488. || head.file_size != _filelength (_fileno (fp))
  2489. || head.file_size_not != ~head.file_size
  2490. || head.nobject_type != nobject_type)
  2491. return 0;
  2492. int counts[nobject_type];
  2493. readf (fp, counts, sizeof counts);
  2494. int i, n;
  2495. for (i = 0, n = 0; i < nobject_type; i++)
  2496. n += counts[i];
  2497. if (n != head.nreps)
  2498. return 0;
  2499. nreps = n;
  2500. laddrp = (ldata_rep **)alloca (sizeof (ldata_rep *) * n);
  2501. i = 0;
  2502. ldata_rep **lp = laddrp;
  2503. #define DECLARE_LDATA(a, b) \
  2504. ldata <a, b>::alloc_reps (lp, counts[i]); lp += counts[i++];
  2505. #include "dataP.h"
  2506. Qnil = rlmap (head.nil);
  2507. #define DECLARE_LDATA(a, b) ldata <a, b>::rdump_reps (fp);
  2508. #include "dataP.h"
  2509. return 1;
  2510. }
  2511. static int dump_flag;
  2512. int
  2513. rdump_xyzzy ()
  2514. {
  2515. FILE *fp = _fsopen (app.dump_image, "rb", _SH_DENYWR);
  2516. if (!fp)
  2517. return 0;
  2518. dump_flag = 0;
  2519. try
  2520. {
  2521. dump_flag = rdump_xyzzy (fp) && getc (fp) == EOF;
  2522. }
  2523. catch (dump_error)
  2524. {
  2525. }
  2526. fclose (fp);
  2527. if (dump_flag)
  2528. {
  2529. #define DECLARE_LDATA(a, b) /* empty */
  2530. #define DECLARE_LARRAY(a, b) ldata<a, b>::array_fixup_displaced_offset ();
  2531. #include "dataP.h"
  2532. ldata <lchunk, Tchunk>::chunk_fixup_data_offset ();
  2533. #define DECLARE_LDATA(a, b) ldata <a, b>::link_unused ();
  2534. #include "dataP.h"
  2535. }
  2536. else
  2537. {
  2538. #define DECLARE_LDATA(a, b) ldata <a, b>::free_all_reps ();
  2539. #include "dataP.h"
  2540. }
  2541. return dump_flag;
  2542. }
  2543. lisp
  2544. Fxyzzy_dumped_p ()
  2545. {
  2546. return boole (dump_flag);
  2547. }
  2548. #ifdef DEBUG_GC
  2549. static void
  2550. output_funcall_mark (FILE *fp, lfns *p, const char *pkg = "")
  2551. {
  2552. for (; p->name; p++)
  2553. if (p->called)
  2554. {
  2555. for (int f = 1; f <= 0x20; f <<= 1)
  2556. putc (p->called & f ? 'o' : ' ', fp);
  2557. putc (p->called & 0x7f ? '*' : ' ', fp);
  2558. putc (p->called & 0x80 ? '@' : ' ', fp);
  2559. fprintf (fp, ": %s%.*s\n", pkg, p->size, p->name);
  2560. }
  2561. }
  2562. void
  2563. output_funcall_mark (FILE *fp)
  2564. {
  2565. fprintf (fp, "Funcall list:\n");
  2566. output_funcall_mark (fp, lsp_fns);
  2567. output_funcall_mark (fp, cl_fns);
  2568. output_funcall_mark (fp, sys_fns, "si:");
  2569. output_funcall_mark (fp, ed_fns);
  2570. }
  2571. #endif /* DEBUG_GC */
  2572. void
  2573. rehash_all_hash_tables ()
  2574. {
  2575. int n = ldata <lhash_table, Thash_table>::count_reps ();
  2576. ldata_rep **r = (ldata_rep **)alloca (sizeof *r * n);
  2577. ldata <lhash_table, Thash_table>::get_reps (r);
  2578. ldata_iter <lhash_table, Thash_table> tables (r, n);
  2579. lhash_table **h = new lhash_table*[n * LDATA_NOBJS (lhash_table)];
  2580. int count = 0;
  2581. for (int i = 0; i < n; i++)
  2582. {
  2583. lhash_table *d = tables.next ();
  2584. for (lhash_table *de = d + LDATA_NOBJS (lhash_table); d < de; d++)
  2585. if (bitisset (used_place (d), bit_index (d)))
  2586. h[count++] = d;
  2587. }
  2588. for (int j = 0; j < count; j++)
  2589. hash_table_rehash (h[j], 0);
  2590. delete[] h;
  2591. }