Changed the makefile system to autoconf/automake.
[cacao.git] / mm / lifespan.c
1 /*
2  * cacao/mm/lifespan.c
3  * $Id: lifespan.c 115 1999-01-20 01:52:45Z phil $
4  */
5
6 #include "mm.h"
7 #include "lifespan.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 typedef struct {
13         unsigned long time;
14         unsigned long number;
15         unsigned long size;
16 } lifespan_object;
17
18 static unsigned long     current_time = 0;
19 static unsigned long     current_number = 0;
20 static lifespan_object** lifespan_objects = NULL;
21 static lifespan_object** lifespan_objects_end = NULL;
22 static void*             lifespan_objects_off = NULL;
23 static FILE*             lifespan_file = NULL;
24
25 static unsigned long     lifespan_histo_size[64] = { 0 };
26 static unsigned long     lifespan_histo_lifespan[64] = { 0 };
27
28 void lifespan_init(void* heap_base, unsigned long heap_size)
29 {
30         current_time = 0;
31
32         lifespan_objects = (lifespan_object**)malloc(heap_size);
33         lifespan_objects_end = ((lifespan_object**)((unsigned long)lifespan_objects + (unsigned long)heap_size));
34         lifespan_objects_off = (void*)((unsigned long)lifespan_objects - (unsigned long)heap_base);
35         lifespan_file = popen("gzip -9 >lifespans.gz", "w");
36
37         if (!lifespan_objects || !lifespan_file) {
38                 fprintf(stderr, "Failed to allocate memory for lifespan-object index / popen lifespan output stream\n");
39                 exit(-1);
40         }
41
42         memset(lifespan_objects, 0, heap_size);
43 }
44
45 static inline void lifespan_free_object(lifespan_object** o)
46 {
47         int size, high = 0;
48         /* file format: alloc time, size, lifespan */
49
50         if (*o) {
51                 fprintf(lifespan_file, 
52                                 "%ld\t%ld\t%ld\t%ld\t%ld\n", 
53                                 (*o)->number, 
54                                 (*o)->time, 
55                                 (*o)->size, 
56                                 current_number - (*o)->number,
57                                 current_time - (*o)->time);
58                 
59                 /* histo_size */
60                 size = (*o)->size;
61                 while (size) {
62                         ++high;
63                         size = size >> 1;
64                 }
65
66                 ++lifespan_histo_size[high];
67
68                 /* histo_life */
69                 high = 0;
70                 size = current_time - (*o)->time;
71                 while (size) {
72                         ++high;
73                         size = size >> 1;
74                 }
75
76                 ++lifespan_histo_lifespan[high];
77
78                 free(*o);
79                 *o = NULL;
80         }
81 }
82
83 void lifespan_close()
84 {
85         if (lifespan_objects) {
86                 while(lifespan_objects < lifespan_objects_end)
87                         lifespan_free_object(--lifespan_objects_end);
88
89                 free(lifespan_objects);
90         }
91
92         if (lifespan_file)
93                 pclose(lifespan_file);
94 }
95
96 void lifespan_emit()
97 {
98         /* emit summary */
99         int i;
100
101         for (i = 4; i < 32; ++i)
102 #if 0
103                 fprintf(stderr, "%Lu-%Lu\t%Lu\n", 
104                                 (1LL << (i-1)), 
105                                 (1LL << i) - 1,
106                                 lifespan_histo_size[i]);
107 #else
108                 fprintf(stderr, "%Lu\n", 
109                                 lifespan_histo_size[i]);
110 #endif
111
112         fprintf(stderr, "\n\n\n");
113
114         for (i = 4; i < 32; ++i)
115                 fprintf(stderr, "%Lu-%Lu\t%Lu\n", 
116                                 (1LL << (i-1)), 
117                                 (1LL << i) - 1,
118                                 lifespan_histo_lifespan[i]);
119 }
120
121 void lifespan_free(void** from, void** limit)
122 {
123         lifespan_object**  object;
124         object = (lifespan_object**)((unsigned long)from + (unsigned long)lifespan_objects_off);
125
126         while (from < limit) {
127                 lifespan_free_object(object++);
128                 ++from;
129         }
130 }
131
132 void lifespan_alloc(void* addr, unsigned long size) 
133 {
134         int high = 0;
135         lifespan_object**  object;
136         object = (lifespan_object**)((unsigned long)addr + (unsigned long)lifespan_objects_off);
137
138         *object = (lifespan_object*)malloc(sizeof(lifespan_object));
139         if (!*object) {
140                 fprintf(stderr, "oops.\n");
141                 exit(-10);
142         }
143         (*object)->time = current_time;
144         (*object)->size = size;
145         (*object)->number = ++current_number;
146
147         while (size) {
148                 ++high;
149                 size = size >> 1;
150         }
151         ++lifespan_histo_size[high];
152         
153         current_time += size;
154 }
155
156 /*
157  * These are local overrides for various environment variables in Emacs.
158  * Please do not remove this and leave it at the end of the file, where
159  * Emacs will automagically detect them.
160  * ---------------------------------------------------------------------
161  * Local variables:
162  * mode: c
163  * indent-tabs-mode: t
164  * c-basic-offset: 4
165  * tab-width: 4
166  * End:
167  */