Mercurial > hg > xemacs-beta
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 } |