comparison src/elhash.c @ 3092:141c2920ea48

[xemacs-hg @ 2005-11-25 01:41:31 by crestani] Incremental Garbage Collector
author crestani
date Fri, 25 Nov 2005 01:42:08 +0000
parents 1e7cc382eb16
children d674024a8674
comparison
equal deleted inserted replaced
3091:c22d8984148c 3092:141c2920ea48
94 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak; 94 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak;
95 static Lisp_Object Qnon_weak, Q_type; 95 static Lisp_Object Qnon_weak, Q_type;
96 96
97 typedef struct htentry 97 typedef struct htentry
98 { 98 {
99 #ifdef NEW_GC
100 struct lrecord_header lheader;
101 #endif /* NEW_GC */
99 Lisp_Object key; 102 Lisp_Object key;
100 Lisp_Object value; 103 Lisp_Object value;
101 } htentry; 104 } htentry;
102 105
103 struct Lisp_Hash_Table 106 struct Lisp_Hash_Table
404 else 407 else
405 write_fmt_string (printcharfun, " 0x%x>", ht->header.uid); 408 write_fmt_string (printcharfun, " 0x%x>", ht->header.uid);
406 } 409 }
407 410
408 static void 411 static void
409 free_hentries (htentry *hentries, 412 free_hentries (
413 #if defined (NEW_GC) && !defined (ERROR_CHECK_STRUCTURES)
414 htentry *UNUSED (hentries),
415 #else
416 htentry *hentries,
417 #endif
410 #ifdef ERROR_CHECK_STRUCTURES 418 #ifdef ERROR_CHECK_STRUCTURES
411 size_t size 419 size_t size
412 #else 420 #else
413 size_t UNUSED (size) 421 size_t UNUSED (size)
414 #endif 422 #endif
415 ) 423 )
416 { 424 {
425 #ifdef NEW_GC
426 #ifdef ERROR_CHECK_STRUCTURES
427 htentry *e, *sentinel;
428
429 for (e = hentries, sentinel = e + size; e < sentinel; e++)
430 mc_free (e);
431 #endif
432 #else /* not NEW_GC */
417 #ifdef ERROR_CHECK_STRUCTURES 433 #ifdef ERROR_CHECK_STRUCTURES
418 /* Ensure a crash if other code uses the discarded entries afterwards. */ 434 /* Ensure a crash if other code uses the discarded entries afterwards. */
419 htentry *e, *sentinel; 435 htentry *e, *sentinel;
420 436
421 for (e = hentries, sentinel = e + size; e < sentinel; e++) 437 for (e = hentries, sentinel = e + size; e < sentinel; e++)
422 * (unsigned long *) e = 0xdeadbeef; /* -559038737 base 10 */ 438 * (unsigned long *) e = 0xdeadbeef; /* -559038737 base 10 */
423 #endif 439 #endif
424 440
425 if (!DUMPEDP (hentries)) 441 if (!DUMPEDP (hentries))
426 xfree (hentries, htentry *); 442 xfree (hentries, htentry *);
443 #endif /* not NEW_GC */
427 } 444 }
428 445
429 static void 446 static void
430 finalize_hash_table (void *header, int for_disksave) 447 finalize_hash_table (void *header, int for_disksave)
431 { 448 {
446 static const struct sized_memory_description htentry_description = { 463 static const struct sized_memory_description htentry_description = {
447 sizeof (htentry), 464 sizeof (htentry),
448 htentry_description_1 465 htentry_description_1
449 }; 466 };
450 467
468 #ifdef NEW_GC
469 static const struct memory_description htentry_weak_description_1[] = {
470 { XD_LISP_OBJECT, offsetof (htentry, key), 0, { 0 }, XD_FLAG_NO_KKCC},
471 { XD_LISP_OBJECT, offsetof (htentry, value), 0, { 0 }, XD_FLAG_NO_KKCC},
472 { XD_END }
473 };
474
475 static const struct sized_memory_description htentry_weak_description = {
476 sizeof (htentry),
477 htentry_weak_description_1
478 };
479
480 DEFINE_LRECORD_IMPLEMENTATION ("hash-table-entry", hash_table_entry,
481 1, /*dumpable-flag*/
482 0, 0, 0, 0, 0,
483 htentry_description_1,
484 Lisp_Hash_Table_Entry);
485 #endif /* NEW_GC */
486
451 static const struct memory_description htentry_union_description_1[] = { 487 static const struct memory_description htentry_union_description_1[] = {
452 /* Note: XD_INDIRECT in this table refers to the surrounding table, 488 /* Note: XD_INDIRECT in this table refers to the surrounding table,
453 and so this will work. */ 489 and so this will work. */
490 #ifdef NEW_GC
491 { XD_LISP_OBJECT_BLOCK_PTR, HASH_TABLE_NON_WEAK,
492 XD_INDIRECT (0, 1), { &htentry_description } },
493 { XD_LISP_OBJECT_BLOCK_PTR, 0, XD_INDIRECT (0, 1),
494 { &htentry_weak_description }, XD_FLAG_UNION_DEFAULT_ENTRY },
495 #else /* not NEW_GC */
454 { XD_BLOCK_PTR, HASH_TABLE_NON_WEAK, XD_INDIRECT (0, 1), 496 { XD_BLOCK_PTR, HASH_TABLE_NON_WEAK, XD_INDIRECT (0, 1),
455 { &htentry_description } }, 497 { &htentry_description } },
456 { XD_BLOCK_PTR, 0, XD_INDIRECT (0, 1), { &htentry_description }, 498 { XD_BLOCK_PTR, 0, XD_INDIRECT (0, 1), { &htentry_description },
457 XD_FLAG_UNION_DEFAULT_ENTRY | XD_FLAG_NO_KKCC }, 499 XD_FLAG_UNION_DEFAULT_ENTRY | XD_FLAG_NO_KKCC },
500 #endif /* not NEW_GC */
458 { XD_END } 501 { XD_END }
459 }; 502 };
460 503
461 static const struct sized_memory_description htentry_union_description = { 504 static const struct sized_memory_description htentry_union_description = {
462 sizeof (htentry *), 505 sizeof (htentry *),
570 ht->count = 0; 613 ht->count = 0;
571 614
572 compute_hash_table_derived_values (ht); 615 compute_hash_table_derived_values (ht);
573 616
574 /* We leave room for one never-occupied sentinel htentry at the end. */ 617 /* We leave room for one never-occupied sentinel htentry at the end. */
618 #ifdef NEW_GC
619 ht->hentries = (htentry *) alloc_lrecord_array (sizeof (htentry),
620 ht->size + 1,
621 &lrecord_hash_table_entry);
622 #else /* not NEW_GC */
575 ht->hentries = xnew_array_and_zero (htentry, ht->size + 1); 623 ht->hentries = xnew_array_and_zero (htentry, ht->size + 1);
624 #endif /* not NEW_GC */
576 625
577 hash_table = wrap_hash_table (ht); 626 hash_table = wrap_hash_table (ht);
578 627
579 if (weakness == HASH_TABLE_NON_WEAK) 628 if (weakness == HASH_TABLE_NON_WEAK)
580 ht->next_weak = Qunbound; 629 ht->next_weak = Qunbound;
968 { 1017 {
969 const Lisp_Hash_Table *ht_old = xhash_table (hash_table); 1018 const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
970 Lisp_Hash_Table *ht = ALLOC_LCRECORD_TYPE (Lisp_Hash_Table, &lrecord_hash_table); 1019 Lisp_Hash_Table *ht = ALLOC_LCRECORD_TYPE (Lisp_Hash_Table, &lrecord_hash_table);
971 COPY_LCRECORD (ht, ht_old); 1020 COPY_LCRECORD (ht, ht_old);
972 1021
1022 #ifdef NEW_GC
1023 ht->hentries = (htentry *) alloc_lrecord_array (sizeof (htentry),
1024 ht_old->size + 1,
1025 &lrecord_hash_table_entry);
1026 #else /* not NEW_GC */
973 ht->hentries = xnew_array (htentry, ht_old->size + 1); 1027 ht->hentries = xnew_array (htentry, ht_old->size + 1);
1028 #endif /* not NEW_GC */
974 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (htentry)); 1029 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (htentry));
975 1030
976 hash_table = wrap_hash_table (ht); 1031 hash_table = wrap_hash_table (ht);
977 1032
978 if (! EQ (ht->next_weak, Qunbound)) 1033 if (! EQ (ht->next_weak, Qunbound))
993 old_size = ht->size; 1048 old_size = ht->size;
994 ht->size = new_size; 1049 ht->size = new_size;
995 1050
996 old_entries = ht->hentries; 1051 old_entries = ht->hentries;
997 1052
1053 #ifdef NEW_GC
1054 ht->hentries = (htentry *) alloc_lrecord_array (sizeof (htentry),
1055 new_size + 1,
1056 &lrecord_hash_table_entry);
1057 #else /* not NEW_GC */
998 ht->hentries = xnew_array_and_zero (htentry, new_size + 1); 1058 ht->hentries = xnew_array_and_zero (htentry, new_size + 1);
1059 #endif /* not NEW_GC */
999 new_entries = ht->hentries; 1060 new_entries = ht->hentries;
1000 1061
1001 compute_hash_table_derived_values (ht); 1062 compute_hash_table_derived_values (ht);
1002 1063
1003 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++) 1064 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
1017 and thus their HASHCODEs have changed. */ 1078 and thus their HASHCODEs have changed. */
1018 void 1079 void
1019 pdump_reorganize_hash_table (Lisp_Object hash_table) 1080 pdump_reorganize_hash_table (Lisp_Object hash_table)
1020 { 1081 {
1021 const Lisp_Hash_Table *ht = xhash_table (hash_table); 1082 const Lisp_Hash_Table *ht = xhash_table (hash_table);
1083 #ifdef NEW_GC
1084 htentry *new_entries =
1085 (htentry *) alloc_lrecord_array (sizeof (htentry), ht->size + 1,
1086 &lrecord_hash_table_entry);
1087 #else /* not NEW_GC */
1022 htentry *new_entries = xnew_array_and_zero (htentry, ht->size + 1); 1088 htentry *new_entries = xnew_array_and_zero (htentry, ht->size + 1);
1089 #endif /* not NEW_GC */
1023 htentry *e, *sentinel; 1090 htentry *e, *sentinel;
1024 1091
1025 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1092 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1026 if (!HTENTRY_CLEAR_P (e)) 1093 if (!HTENTRY_CLEAR_P (e))
1027 { 1094 {
1031 *probe = *e; 1098 *probe = *e;
1032 } 1099 }
1033 1100
1034 memcpy (ht->hentries, new_entries, ht->size * sizeof (htentry)); 1101 memcpy (ht->hentries, new_entries, ht->size * sizeof (htentry));
1035 1102
1103 #ifdef NEW_GC
1104 mc_free (new_entries);
1105 #else /* not NEW_GC */
1036 xfree (new_entries, htentry *); 1106 xfree (new_entries, htentry *);
1107 #endif /* not NEW_GC */
1037 } 1108 }
1038 1109
1039 static void 1110 static void
1040 enlarge_hash_table (Lisp_Hash_Table *ht) 1111 enlarge_hash_table (Lisp_Hash_Table *ht)
1041 { 1112 {
1759 1830
1760 void 1831 void
1761 init_elhash_once_early (void) 1832 init_elhash_once_early (void)
1762 { 1833 {
1763 INIT_LRECORD_IMPLEMENTATION (hash_table); 1834 INIT_LRECORD_IMPLEMENTATION (hash_table);
1835 #ifdef NEW_GC
1836 INIT_LRECORD_IMPLEMENTATION (hash_table_entry);
1837 #endif /* NEW_GC */
1764 1838
1765 /* This must NOT be staticpro'd */ 1839 /* This must NOT be staticpro'd */
1766 Vall_weak_hash_tables = Qnil; 1840 Vall_weak_hash_tables = Qnil;
1767 dump_add_weak_object_chain (&Vall_weak_hash_tables); 1841 dump_add_weak_object_chain (&Vall_weak_hash_tables);
1768 } 1842 }