CACAO
profile.c
Go to the documentation of this file.
1 /* VM profiling support stuff
2 
3  Copyright (C) 2001,2003 Free Software Foundation, Inc.
4 
5  This file is part of Gforth.
6 
7  Gforth is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation; either version 2
10  of the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20 */
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "vm/jit/intrp/intrp.h"
26 
27 /* data structure: simple hash table with external chaining */
28 
29 #define HASH_SIZE (1<<20)
30 #define hash(p) ((((Cell)(p))/sizeof(Inst))&(HASH_SIZE-1))
31 
32 #ifdef __GNUC__
33 typedef long long long_long;
34 #else
35 typedef long long_long;
36 #endif
37 
38 struct block_count {
39  struct block_count *next; /* next in hash table */
40  struct block_count *fallthrough; /* the block that this one falls
41  through to without SUPER_END */
42  Inst *ip;
44  char **insts;
45  size_t ninsts;
46 };
47 
49 
51 {
52  block_count *b = blocks[hash(ip)];
53 
54  while (b!=NULL && b->ip!=ip)
55  b = b->next;
56  return b;
57 }
58 
59 /* looks up present elements, inserts absent elements */
61 {
62  block_count *b = block_lookup(ip);
63  block_count *new;
64 
65  if (b != NULL)
66  return b;
67  new = (block_count *)malloc(sizeof(block_count));
68  new->next = blocks[hash(ip)];
69  new->fallthrough = NULL;
70  new->ip = ip;
71  new->count = (long_long)0;
72  new->insts = malloc(1);
73  assert(new->insts != NULL);
74  new->ninsts = 0;
75  blocks[hash(ip)] = new;
76  return new;
77 }
78 
79 void add_inst(block_count *b, char *inst)
80 {
81  b->insts = realloc(b->insts, (b->ninsts+1) * sizeof(char *));
82  b->insts[b->ninsts++] = inst;
83 }
84 
86 {
87  vm_block_insert(ip)->count++;
88 }
89 
91 {
92  vm_block_insert(ip)->count--;
93 }
94 
96 {
97  Inst *ip = b->ip;
98  block_count *next_block=NULL;
99 
100  if (b->count == 0)
101  return;
102  while (next_block == NULL) {
103 #include "java-profile.i"
104  /* else */
105  {
106  add_inst(b,"unknown");
107  ip++;
108  }
109  _endif_:
110  next_block = block_lookup(ip);
111  }
112  /* we fell through, so set fallthrough and update the count */
113  b->fallthrough = next_block;
114  /* also update the counts of all following fallthrough blocks that
115  have already been processed */
116  while (next_block != NULL) {
117  next_block->count += b->count;
118  next_block = next_block->fallthrough;
119  }
120 }
121 
122 /* Deal with block entry by falling through from non-SUPER_END
123  instructions. And fill the insts and ninsts fields. */
124 void postprocess(void)
125 {
126  size_t i;
127 
128  for (i=0; i<HASH_SIZE; i++) {
129  block_count *b = blocks[i];
130  for (; b!=0; b = b->next)
132  }
133 }
134 
135 #if 0
136 void print_block(FILE *file, block_count *b)
137 {
138  size_t i;
139 
140  fprintf(file,"%14lld\t",b->count);
141  for (i=0; i<b->ninsts; i++)
142  fprintf(file, "%s ", b->insts[i]);
143  putc('\n', file);
144 }
145 #endif
146 
147 void print_block(FILE *file, block_count *b)
148 {
149  size_t i,j,k;
150 
151  for (i=2; i<12; i++)
152  for (j=0; i+j<=b->ninsts; j++) {
153  fprintf(file,"%14lld\t",b->count);
154  for (k=j; k<i+j; k++)
155  fprintf(file, "%s ", b->insts[k]);
156  putc('\n', file);
157  }
158 }
159 
160 void vm_print_profile(FILE *file)
161 {
162  size_t i;
163 
164  postprocess();
165  for (i=0; i<HASH_SIZE; i++) {
166  block_count *b = blocks[i];
167  for (; b!=0; b = b->next)
168  print_block(file, b);
169  }
170 }
#define hash(p)
Definition: profile.c:30
#define HASH_SIZE
Definition: profile.c:29
void postprocess_block(block_count *b)
Definition: profile.c:95
char ** insts
Definition: profile.c:44
long_long count
Definition: profile.c:43
block_count * block_lookup(Inst *ip)
Definition: profile.c:50
Inst * ip
Definition: profile.c:42
void postprocess(void)
Definition: profile.c:124
void vm_print_profile(FILE *file)
Definition: profile.c:160
block_count * vm_block_insert(Inst *ip)
Definition: profile.c:60
#define vm_uncount_block(_ip)
Definition: engine.c:115
void * Inst
Definition: intrp.h:58
void vm_count_block(Inst *ip)
Definition: profile.c:85
void print_block(FILE *file, block_count *b)
Definition: profile.c:147
MIIterator i
struct block_count * fallthrough
Definition: profile.c:40
size_t ninsts
Definition: profile.c:45
void add_inst(block_count *b, char *inst)
Definition: profile.c:79
long long_long
Definition: profile.c:35
struct block_count * next
Definition: profile.c:39
block_count * blocks[HASH_SIZE]
Definition: profile.c:48
#define ip
Definition: md-asm.hpp:59