I suggest the following as being more intuitive, more maintainable,
and also being more correct. You are making the non-portable
assumption that the compiler lays out structs like an array. In fact,
the compiler can order key and value any way it likes. You did call
it the _portable_ dumper.
Of course, you might object that the proposed change makes pdump_load
slower. If you really really think this micro-optimization is worth
it (I don't) then you can change the declaration of hentry to be
Lisp_Object hentry[2];
and change all the references to hentry->key, e.g. using
#define HENTRY_KEY(hentry) hentry[0]
#define HENTRY_VALUE(hentry) hentry[1]
Index: elhash.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/elhash.c,v
retrieving revision 1.14.2.17
diff -u -r1.14.2.17 elhash.c
--- elhash.c 2000/01/08 07:51:23 1.14.2.17
+++ elhash.c 2000/01/26 00:40:53
@@ -374,7 +374,8 @@
}
static const struct lrecord_description hentry_description_1[] = {
- { XD_LISP_OBJECT, offsetof(hentry, key), 2 },
+ { XD_LISP_OBJECT, offsetof(hentry, key), 1 },
+ { XD_LISP_OBJECT, offsetof(hentry, value), 1 },
{ XD_END }
};
I don't understand where the zero'ed ends of strings and hash_tables
are being stored and/or restored. The size of the data member in a
string or a hash_table refers to the "real" data, but strings have a
NUL byte at the end, and hash table entries have a null sentinel entry
at the end. How are these being restored?
I've been purifying xemacs built with pdump. creating the dump file
runs cleanly for me now. However, after running the test suite, I get
lots of memory leak warnings I don't understand like this:
(elhash.c source file pointers are off by one)
MLK: 94240 bytes leaked in 254 blocks
This memory was allocated from:
malloc [rtlib.o]
calloc [rtlib.o]
xcalloc [alloc.c:293]
xmalloc_and_zero [alloc.c:302]
resize_hash_table [elhash.c:894]
*** WARNING: Source file is newer, display may be incorrect
ht->size = new_size;
old_entries = ht->hentries;
=>
ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
new_entries = ht->hentries;
reorganize_hash_table [elhash.c:915]
*** WARNING: Source file is newer, display may be incorrect
void
reorganize_hash_table (Lisp_Hash_Table *ht)
=> {
resize_hash_table (ht, ht->size);
}
pdump_load [alloc.c:5132]
for (i=0; i<rt->count; i++)
{
struct Lisp_Hash_Table *ht = XHASH_TABLE (*(Lisp_Object
*)p);
=> reorganize_hash_table (ht);
p += sizeof (EMACS_INT);
}
break;
xemacs_21_2_b27_sparc_sun_solaris2_6 [emacs.c:854]
main [emacs.c:2251]
_start [crt1.o]
Block of 6304 bytes at 0x10ba628
Block of 3664 bytes (2 times); last block at 0x10aacd8
Block of 2784 bytes (2 times); last block at 0x10b1648
Block of 1584 bytes (4 times); last block at 0x10b9f38
Block of 1200 bytes at 0x10a6258
Block of 864 bytes (8 times); last block at 0x10b5cc8
Block of 640 bytes (7 times); last block at 0x10b65f8
Block of 480 bytes (4 times); last block at 0x10a7468
Block of 336 bytes (2 times); last block at 0x10bc138
Block of 240 bytes (223 times); last block at 0x10bbf88
MLK: 480 bytes leaked at 0x115d0a0
This memory was allocated from:
malloc [rtlib.o]
calloc [rtlib.o]
xcalloc [alloc.c:293]
xmalloc_and_zero [alloc.c:302]
resize_hash_table [elhash.c:894]
*** WARNING: Source file is newer, display may be incorrect
ht->size = new_size;
old_entries = ht->hentries;
=>
ht->hentries = xnew_array_and_zero (hentry, new_size + 1);
new_entries = ht->hentries;
enlarge_hash_table [elhash.c:923]
*** WARNING: Source file is newer, display may be incorrect
enlarge_hash_table (Lisp_Hash_Table *ht)
{
size_t new_size =
=> hash_table_size ((size_t) ((double) ht->size *
ht->rehash_size));
resize_hash_table (ht, new_size);
}
Fputhash [elhash.c:967]
*** WARNING: Source file is newer, display may be incorrect
e->key = key;
e->value = value;
=> if (++ht->count >= ht->rehash_count)
enlarge_hash_table (ht);
return value;
keymap_store_internal [keymap.c:608]
keymap_store [keymap.c:673]
Fdefine_key [keymap.c:1949]
Feval [eval.c:2975]
readevalloop [lread.c:1448]
Fload_internal [lread.c:736]
Ffuncall [eval.c:3175]
execute_optimized_program [bytecode.c:747]
funcall_compiled_function [bytecode.c:519]
Ffuncall [eval.c:3210]
execute_optimized_program [bytecode.c:747]
Fbyte_code [bytecode.c:2404]
Feval [eval.c:2975]
condition_case_1 [eval.c:1629]
condition_case_3 [eval.c:1710]
execute_rare_opcode [bytecode.c:1272]
execute_optimized_program [bytecode.c:657]
funcall_compiled_function [bytecode.c:519]
Ffuncall [eval.c:3210]
mapcar1 [fns.c:3112]
Fmapcar [fns.c:3218]
Ffuncall [eval.c:3175]
execute_optimized_program [bytecode.c:747]
funcall_compiled_function [bytecode.c:519]
Ffuncall [eval.c:3210]
MLK: 336 bytes leaked at 0x1109388
This memory was allocated from:
malloc [rtlib.o]
calloc [rtlib.o]
xcalloc [alloc.c:293]
xmalloc_and_zero [alloc.c:302]
resize_hash_table [elhash.c:894]
enlarge_hash_table [elhash.c:923]
Fputhash [elhash.c:967]
keymap_store_inverse_internal [keymap.c:528]
keymap_store_internal [keymap.c:610]
keymap_store [keymap.c:673]
Fdefine_key [keymap.c:1949]
Ffuncall [eval.c:3175]
execute_optimized_program [bytecode.c:747]
Fbyte_code [bytecode.c:2404]
Feval [eval.c:2975]
readevalloop [lread.c:1448]
Fload_internal [lread.c:736]
Ffuncall [eval.c:3175]
execute_optimized_program [bytecode.c:747]
funcall_compiled_function [bytecode.c:519]
Ffuncall [eval.c:3210]
execute_optimized_program [bytecode.c:747]
Fbyte_code [bytecode.c:2404]
Feval [eval.c:2975]
condition_case_1 [eval.c:1629]
condition_case_3 [eval.c:1710]
execute_rare_opcode [bytecode.c:1272]
execute_optimized_program [bytecode.c:657]
funcall_compiled_function [bytecode.c:519]
Ffuncall [eval.c:3210]
mapcar1 [fns.c:3112]
Fmapcar [fns.c:3218]
Martin