1 /* VM profiling support stuff
3 Copyright (C) 2001,2003 Free Software Foundation, Inc.
5 This file is part of Gforth.
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.
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.
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.
25 #include "vm/jit/intrp/intrp.h"
27 /* data structure: simple hash table with external chaining */
29 #define HASH_SIZE (1<<20)
30 #define hash(p) ((((Cell)(p))/sizeof(Inst))&(HASH_SIZE-1))
33 typedef long long long_long;
35 typedef long long_long;
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 */
48 block_count *blocks[HASH_SIZE];
50 block_count *block_lookup(Inst *ip)
52 block_count *b = blocks[hash(ip)];
54 while (b!=NULL && b->ip!=ip)
59 /* looks up present elements, inserts absent elements */
60 block_count *vm_block_insert(Inst *ip)
62 block_count *b = block_lookup(ip);
67 new = (block_count *)malloc(sizeof(block_count));
68 new->next = blocks[hash(ip)];
69 new->fallthrough = NULL;
71 new->count = (long_long)0;
72 new->insts = malloc(1);
73 assert(new->insts != NULL);
75 blocks[hash(ip)] = new;
79 void add_inst(block_count *b, char *inst)
81 b->insts = realloc(b->insts, (b->ninsts+1) * sizeof(char *));
82 b->insts[b->ninsts++] = inst;
85 void vm_count_block(Inst *ip)
87 vm_block_insert(ip)->count++;
90 void vm_uncount_block(Inst *ip)
92 vm_block_insert(ip)->count--;
95 void postprocess_block(block_count *b)
98 block_count *next_block=NULL;
102 while (next_block == NULL) {
103 #include "java-profile.i"
106 add_inst(b,"unknown");
110 next_block = block_lookup(ip);
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;
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)
128 for (i=0; i<HASH_SIZE; i++) {
129 block_count *b = blocks[i];
130 for (; b!=0; b = b->next)
131 postprocess_block(b);
136 void print_block(FILE *file, block_count *b)
140 fprintf(file,"%14lld\t",b->count);
141 for (i=0; i<b->ninsts; i++)
142 fprintf(file, "%s ", b->insts[i]);
147 void print_block(FILE *file, block_count *b)
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]);
160 void vm_print_profile(FILE *file)
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);