source: project/release/4/heap-o-rama/trunk/low-level-stuff.c @ 19368

Last change on this file since 19368 was 19368, checked in by felix winkelmann, 10 years ago

heap-o-rama: don't drop existing hook

File size: 2.4 KB
Line 
1/* low-level-stuff.c */
2
3
4#include <assert.h>
5
6
7static int min_size = 1, max_size = 100;
8static int hash_table_size = 0;
9static C_word *hash_table = NULL;
10static int gc_happened = 0;
11static void (*old_hook)(int, long);
12
13
14static int
15filter_func(C_word x, C_word protos)
16{
17  int i;
18  int plen = C_header_size(protos);
19  int size = C_header_size(x);
20
21  if(size < min_size || size > max_size) return 0;
22
23  for(i = 0; i < plen; ++i) {
24    C_word y = C_block_item(protos, i);
25
26    if(C_header_bits(x) == C_STRUCTURE_TYPE) {
27      if(C_header_bits(y) == C_STRUCTURE_TYPE && C_block_item(x, 0) == C_block_item(y, 0))
28        return 1;
29    }
30    else if(C_header_bits(x) == C_header_bits(y)) return 1;
31  }
32
33  return 0;
34}
35
36
37static C_word *
38hash_lookup(C_word x)
39{
40  unsigned long n = (unsigned long)x;
41  int k = (n & 0xffff) ^ (n >> 16);
42  int index = (k % hash_table_size) * 2;
43  int max_tries = 100;
44
45  while(max_tries > 0) {
46    C_word y = hash_table[ index ];
47
48    if(y == 0 || x == y) return hash_table + index;
49
50    index = (index + 2) % (hash_table_size * 2);
51    ++max_tries;
52  }
53
54  return NULL;
55}
56
57
58static void
59hash_objects(C_word otable, int len)
60{
61  int i;
62  int hlen = len * 2;
63
64  if(hash_table_size != hlen) {
65    hash_table = (C_word *)realloc(hash_table, sizeof(C_word) * 2 * hlen);
66    assert(hash_table);
67    hash_table_size = hlen;
68  }
69
70  memset(hash_table, 0, sizeof(C_word) * 2 * hlen);
71
72  for(i = 0; i < len; ++i) {
73    C_word x = C_block_item(otable, i);
74    C_word *hentry = hash_lookup(x);
75
76    *hentry = x;
77    hentry[ 1 ] = C_fix(i);
78  }
79}
80
81
82static void
83post_gc_hook(int reason, long ms)
84{
85  if(old_hook) old_hook(reason, ms);
86
87  if(reason > 0) gc_happened = 1;
88}
89
90
91static void
92setup_low_level_stuff(int mins, int maxs)
93{
94  old_hook = C_post_gc_hook;
95  C_post_gc_hook = post_gc_hook;
96  min_size = mins;
97  max_size = maxs;
98}
99
100
101static void
102find_children(C_word otable, C_word ctable, int n)
103{
104  int i, j;
105
106  hash_objects(otable, n);
107
108  for(i = 0; i < n; ++i) {
109    C_word x = C_block_item(otable, i);
110    C_word c = C_block_item(ctable, i);
111    int len = C_header_size(c) - 1;
112    int o = 1;
113
114    if((C_header_bits(x) & C_BYTEBLOCK_BIT) != 0)
115      continue;
116
117    for(j = (C_header_bits(x) & C_SPECIALBLOCK_BIT) != 0 ? 1 : 0; j < len; ++j) {
118      C_word y = C_block_item(x, j);
119      C_word *h = hash_lookup(y);
120     
121      if(*h != 0) {
122        C_set_block_item(c, o, h[ 1 ]);
123        ++o;
124      }
125    }
126
127    C_set_block_item(c, 0, C_fix(o - 1));
128  }
129}
Note: See TracBrowser for help on using the repository browser.