diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1997-04-11 13:57:04 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1997-04-11 13:57:04 +0000 |
commit | dea956a7d31ae02bfd91d6d2d8c8b4bf65b8655f (patch) | |
tree | 9aad15d028b25674f565541f8b2b080bd5999a2f /byterun/extern.c | |
parent | 47cf17d88d8f2dd4b62387a7f51de2d17da05c08 (diff) | |
download | ocaml-dea956a7d31ae02bfd91d6d2d8c8b4bf65b8655f.tar.gz |
debugger.c: suppression de variables inutilisees
extern.c intern.h: garder la hashtable d'une fois sur l'autre,
ne pas la remettre a zero entre deux output_value (couteux si
bcp de petits messages)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@1493 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'byterun/extern.c')
-rw-r--r-- | byterun/extern.c | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/byterun/extern.c b/byterun/extern.c index 74a2ee13f1..21720b232f 100644 --- a/byterun/extern.c +++ b/byterun/extern.c @@ -30,11 +30,12 @@ typedef unsigned long byteoffset_t; struct extern_obj { - value obj; byteoffset_t ofs; + value obj; }; -static struct extern_obj * extern_table; +static byteoffset_t initial_ofs = 1; +static struct extern_obj * extern_table = NULL; static unsigned long extern_table_size; #ifdef ARCH_SIXTYFOUR @@ -43,20 +44,22 @@ static unsigned long extern_table_size; #define Hash(v) (((unsigned long) ((v) >> 2)) % extern_table_size) #endif +/* Allocate a new extern table */ static void alloc_extern_table() { asize_t i; - extern_table = (struct extern_obj *) - stat_alloc(extern_table_size * sizeof(struct extern_obj)); - for (i = 0; i < extern_table_size; i++) extern_table[i].obj = 0; + stat_alloc(extern_table_size * sizeof(struct extern_obj)); + for (i = 0; i < extern_table_size; i++) extern_table[i].ofs = 0; } +/* Grow the extern table */ static void resize_extern_table() { asize_t oldsize; struct extern_obj * oldtable; value obj; + byteoffset_t ofs; asize_t i, h; oldsize = extern_table_size; @@ -64,20 +67,33 @@ static void resize_extern_table() extern_table_size = 2 * extern_table_size; alloc_extern_table(); for (i = 0; i < oldsize; i++) { - obj = oldtable[i].obj; - if (obj != 0) { + ofs = oldtable[i].ofs; + if (ofs >= initial_ofs) { + obj = oldtable[i].obj; h = Hash(obj); - while (extern_table[h].obj != 0) { + while (extern_table[h].ofs >= initial_ofs) { h++; if (h >= extern_table_size) h = 0; } + extern_table[h].ofs = ofs; extern_table[h].obj = obj; - extern_table[h].ofs = oldtable[i].ofs; } } stat_free((char *) oldtable); } +/* Free the extern table. We keep it around for next call if + it's still small (we did not grow it) and the initial offset + does not risk running over next time. */ +static void free_extern_table() +{ + if (extern_table_size > INITIAL_EXTERN_TABLE_SIZE || + initial_ofs >= INITIAL_OFFSET_MAX) { + stat_free((char *) extern_table); + extern_table = NULL; + } +} + /* To buffer the output */ static char * extern_block, * extern_ptr, * extern_limit; @@ -181,10 +197,13 @@ static byteoffset_t obj_counter; /* Number of objects emitted so far */ static unsigned long size_32; /* Size in words of 32-bit block for struct. */ static unsigned long size_64; /* Size in words of 64-bit block for struct. */ -static void extern_cleanup() +static void extern_invalid_argument(msg) + char * msg; { stat_free(extern_block); - stat_free((char *) extern_table); + initial_ofs += obj_counter; + free_extern_table(); + invalid_argument(msg); } static void extern_rec(v) @@ -206,8 +225,7 @@ static void extern_rec(v) } else writecode32(CODE_INT32, n); } else if (!Is_atom(v) && !Is_young(v) && !Is_in_heap(v)) { - extern_cleanup(); - invalid_argument("output_value: abstract value"); + extern_invalid_argument("output_value: abstract value"); } else { header_t hd = Hd_val(v); tag_t tag = Tag_hd(hd); @@ -225,9 +243,9 @@ static void extern_rec(v) /* Check if already seen */ if (2 * obj_counter >= extern_table_size) resize_extern_table(); h = Hash(v); - while (extern_table[h].obj != 0) { + while (extern_table[h].ofs >= initial_ofs) { if (extern_table[h].obj == v) { - byteoffset_t d = obj_counter - extern_table[h].ofs; + byteoffset_t d = obj_counter - (extern_table[h].ofs - initial_ofs); if (d < 0x100) { writecode8(CODE_SHARED8, d); } else if (d < 0x10000) { @@ -241,8 +259,8 @@ static void extern_rec(v) if (h >= extern_table_size) h = 0; } /* Not seen yet. Record the object and output its contents. */ + extern_table[h].ofs = initial_ofs + obj_counter; extern_table[h].obj = v; - extern_table[h].ofs = obj_counter; obj_counter++; switch(tag) { case String_tag: { @@ -260,10 +278,8 @@ static void extern_rec(v) break; } case Double_tag: { - if (sizeof(double) != 8) { - extern_cleanup(); - invalid_argument("output_value: non-standard floats"); - } + if (sizeof(double) != 8) + extern_invalid_argument("output_value: non-standard floats"); Write(CODE_DOUBLE_NATIVE); writeblock((char *) v, 8); size_32 += 1 + 2; @@ -272,10 +288,8 @@ static void extern_rec(v) } case Double_array_tag: { mlsize_t nfloats; - if (sizeof(double) != 8) { - extern_cleanup(); - invalid_argument("output_value: non-standard floats"); - } + if (sizeof(double) != 8) + extern_invalid_argument("output_value: non-standard floats"); nfloats = Wosize_val(v) / Double_wosize; if (nfloats < 0x100) { writecode8(CODE_DOUBLE_ARRAY8_NATIVE, nfloats); @@ -289,13 +303,11 @@ static void extern_rec(v) } case Abstract_tag: case Final_tag: - extern_cleanup(); - invalid_argument("output_value: abstract value"); + extern_invalid_argument("output_value: abstract value"); break; case Closure_tag: case Infix_tag: - extern_cleanup(); - invalid_argument("output_value: functional value"); + extern_invalid_argument("output_value: functional value"); break; default: { mlsize_t i; @@ -319,9 +331,15 @@ static long extern_value(v) value v; { long res_len; + + /* Allocate buffer for holding the result */ alloc_extern_block(); + /* Allocate hashtable of objects already seen, if needed */ extern_table_size = INITIAL_EXTERN_TABLE_SIZE; - alloc_extern_table(); + if (extern_table == NULL) { + alloc_extern_table(); + initial_ofs = 1; + } obj_counter = 0; size_32 = 0; size_64 = 0; @@ -331,8 +349,11 @@ static long extern_value(v) extern_ptr += 4*4; /* Marshal the object */ extern_rec(v); - /* Free the table of shared objects */ - stat_free((char *) extern_table); + /* Update initial offset for next call to extern_value(), + if we decide to keep the table of shared objects. */ + initial_ofs += obj_counter; + /* Free the table of shared objects (if needed) */ + free_extern_table(); /* Write the sizes */ #ifdef ARCH_SIXTYFOUR if (size_32 >= (1L << 32) || size_64 >= (1L << 32)) { |