narray first check in
[cacao.git] / jit.c
1 /* jit.c ***********************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties.
6
7         Contains the functions which translates a JavaVM method into native code.
8         This is the new version of the compiler which is a lot faster and has new
9         exception handling schemes. The main function is new_comp.
10
11         Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
12                  Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
13
14         Last Change: 1997/11/05
15
16 *******************************************************************************/
17
18 #include <signal.h>
19
20 #include "global.h"
21 #include "tables.h"
22 #include "loader.h"
23 #include "jit.h"
24 #include "builtin.h"
25 #include "native.h"
26 #include "asmpart.h"
27
28 #include "threads/thread.h"
29
30 /* include compiler data types ************************************************/ 
31
32 #include "jit/jitdef.h"
33 #include "narray/loop.h"
34
35
36 /* global switches ************************************************************/
37 int num_compiled_m = 0;
38 int myCount;
39
40 bool compileverbose = false;
41 bool showstack = false;
42 bool showdisassemble = false; 
43 bool showddatasegment = false; 
44 bool showintermediate = false;
45 int  optimizelevel = 0;
46
47 bool checkbounds = true;
48 bool checknull = true;
49 bool checkfloats = true;
50 bool checksync = true;
51 bool opt_loops = false;
52
53 bool getcompilingtime = false;
54 long compilingtime = 0;
55
56 int  has_ext_instr_set = 0;
57
58 bool statistics = false;         
59
60 int count_jit_calls = 0;
61 int count_methods = 0;
62 int count_spills = 0;
63 int count_pcmd_activ = 0;
64 int count_pcmd_drop = 0;
65 int count_pcmd_zero = 0;
66 int count_pcmd_const_store = 0;
67 int count_pcmd_const_alu = 0;
68 int count_pcmd_const_bra = 0;
69 int count_pcmd_load = 0;
70 int count_pcmd_move = 0;
71 int count_load_instruction = 0;
72 int count_pcmd_store = 0;
73 int count_pcmd_store_comb = 0;
74 int count_dup_instruction = 0;
75 int count_pcmd_op = 0;
76 int count_pcmd_mem = 0;
77 int count_pcmd_met = 0;
78 int count_pcmd_bra = 0;
79 int count_pcmd_table = 0;
80 int count_pcmd_return = 0;
81 int count_pcmd_returnx = 0;
82 int count_check_null = 0;
83 int count_check_bound = 0;
84 int count_max_basic_blocks = 0;
85 int count_basic_blocks = 0;
86 int count_javainstr = 0;
87 int count_max_javainstr = 0;
88 int count_javacodesize = 0;
89 int count_javaexcsize = 0;
90 int count_calls = 0;
91 int count_tryblocks = 0;
92 int count_code_len = 0;
93 int count_data_len = 0;
94 int count_cstub_len = 0;
95 int count_nstub_len = 0;
96 int count_max_new_stack = 0;
97 int count_upper_bound_new_stack = 0;
98 static int count_block_stack_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
99 int *count_block_stack = count_block_stack_init;
100 static int count_analyse_iterations_init[5] = {0, 0, 0, 0, 0};
101 int *count_analyse_iterations = count_analyse_iterations_init;
102 static int count_method_bb_distribution_init[9] = {0, 0, 0, 0, 0,  0, 0, 0, 0};
103 int *count_method_bb_distribution = count_method_bb_distribution_init;
104 static int count_block_size_distribution_init[18] = {0, 0, 0, 0, 0,
105         0, 0, 0, 0, 0,   0, 0, 0, 0, 0,   0, 0, 0};
106 int *count_block_size_distribution = count_block_size_distribution_init;
107 static int count_store_length_init[21] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
108                                           0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0};
109 int *count_store_length = count_store_length_init;
110 static int count_store_depth_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0};
111 int *count_store_depth = count_store_depth_init;
112
113
114
115 /* global compiler variables **************************************************/
116
117                                 /* data about the currently compiled method   */
118
119 static classinfo  *class;       /* class the compiled method belongs to       */
120 static methodinfo *method;      /* pointer to method info of compiled method  */
121 static unicode    *descriptor;  /* type descriptor of compiled method         */
122 static int         mparamcount; /* number of parameters (incl. this)          */
123 static u1         *mparamtypes; /* types of all parameters (TYPE_INT, ...)    */
124 static int         mreturntype; /* return type of method                      */
125         
126 static int maxstack;            /* maximal JavaVM stack size                  */
127 static int maxlocals;           /* maximal number of local JavaVM variables   */
128 static int jcodelength;         /* length of JavaVM-codes                     */
129 static u1 *jcode;               /* pointer to start of JavaVM-code            */
130 static int exceptiontablelength;/* length of exception table                  */
131 static xtable *extable;         /* pointer to start of exception table        */
132 static exceptiontable *raw_extable;
133
134 static int block_count;         /* number of basic blocks                     */
135 static basicblock *block;       /* points to basic block array                */
136 static int *block_index;        /* a table which contains for every byte of   */
137                                 /* JavaVM code a basic block index if at this */
138                                 /* byte there is the start of a basic block   */
139
140 static int instr_count;         /* number of JavaVM instructions              */
141 static instruction *instr;      /* points to intermediate code instructions   */
142
143 static int stack_count;         /* number of stack elements                   */
144 static stackelement *stack;     /* points to intermediate code instructions   */
145
146 static bool isleafmethod;       /* true if a method doesn't call subroutines  */
147
148 static basicblock *last_block;  /* points to the end of the BB list           */
149
150 /* list of all classes used by the compiled method which have to be           */
151 /* initialised (if not already done) before execution of this method          */
152
153 static chain *uninitializedclasses;  
154                                 
155
156 /* include compiler subsystems ************************************************/
157
158 #include "ngen.h"        /* code generator header file                 */ 
159 #include "disass.c"      /* disassembler (for debug purposes only)     */ 
160 #include "jit/mcode.c"          /* code generation tool functions             */ 
161 #include "jit/parse.c"          /* parsing of JavaVM code                     */ 
162 #include "jit/reg.c"            /* register allocation and support routines   */ 
163 #include "jit/stack.c"          /* analysing the stack operations             */ 
164 #include "sysdep/ngen.c"        /* code generator                             */ 
165 #include "narray/graph.c"       /* array bound removal                        */
166 #include "narray/loop.c"        /* array bound removal                        */
167 #include "narray/tracing.c"     /* array bound removal                        */
168 #include "narray/analyze.c"     /* array bound removal                        */
169
170
171 /* dummy function, used when there is no JavaVM code available                */
172
173 static void* do_nothing_function() 
174 {
175         return NULL;
176 }
177
178
179 #ifdef OLD_COMPILER
180 extern bool newcompiler;
181 methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*/
182 #endif
183
184
185 /* jit_compile *****************************************************************
186
187         jit_compile, new version of compiler, translates one method to machine code
188
189 *******************************************************************************/
190
191 methodptr jit_compile(methodinfo *m)
192 {
193         int  dumpsize, i, j, k;
194         long starttime = 0;
195         long stoptime  = 0;
196         basicblock *b;
197         instruction *ip;
198         stackptr sp;
199
200         basicblock *bptr;
201         stackptr sptr;
202         int cnt;
203
204
205
206 #ifdef OLD_COMPILER
207         if (!newcompiler) {
208                 return compiler_compile(m);
209                 }
210 #endif
211
212         /* if method has been already compiled return immediately */
213
214         count_jit_calls++;
215
216         if (m->entrypoint)
217                 return m->entrypoint;
218
219         count_methods++;
220
221         intsDisable();      /* disable interrupts */
222         
223
224         /* mark start of dump memory area */
225
226         dumpsize = dump_size ();
227
228         /* measure time */
229
230         if (getcompilingtime)
231                 starttime = getcputime();
232
233         /* if there is no javacode print error message and return empty method    */
234
235         if (! m->jcode) {
236                 sprintf(logtext, "No code given for: ");
237                 unicode_sprint(logtext+strlen(logtext), m->class->name);
238                 strcpy(logtext+strlen(logtext), ".");
239                 unicode_sprint(logtext+strlen(logtext), m->name);
240                 unicode_sprint(logtext+strlen(logtext), m->descriptor);
241                 dolog();
242                 intsRestore();                             /* enable interrupts again */
243                 return (methodptr) do_nothing_function;    /* return empty method     */
244                 }
245
246         /* print log message for compiled method */
247
248         if (compileverbose) {
249                 sprintf(logtext, "Compiling: ");
250                 unicode_sprint(logtext+strlen(logtext), m->class->name);
251                 strcpy(logtext+strlen(logtext), ".");
252                 unicode_sprint(logtext+strlen(logtext), m->name);
253                 unicode_sprint(logtext+strlen(logtext), m->descriptor);
254                 dolog ();
255                 }
256
257
258         /* initialisation of variables and subsystems */
259
260         isleafmethod = true;
261
262         method = m;
263         class = m->class;
264         descriptor = m->descriptor;
265         maxstack = m->maxstack;
266         maxlocals = m->maxlocals;
267         jcodelength = m->jcodelength;
268         jcode = m->jcode;
269         exceptiontablelength = m->exceptiontablelength;
270         raw_extable = m->exceptiontable;
271
272 #ifdef STATISTICS
273         count_tryblocks += exceptiontablelength;
274         count_javacodesize += jcodelength + 18;
275         count_javaexcsize += exceptiontablelength * 8;
276 #endif
277
278         /* initialise parameter type descriptor */
279
280         descriptor2types (m);
281         mreturntype = m->returntype;
282         mparamcount = m->paramcount;
283         mparamtypes = m->paramtypes;
284
285         /* initialize class list with class the compiled method belongs to */
286
287         uninitializedclasses = chain_new(); 
288         compiler_addinitclass (m->class);
289
290
291         /* call the compiler passes ***********************************************/
292         
293         reg_init();
294
295         local_init();
296
297         mcode_init();
298
299         parse();
300
301         analyse_stack();
302    
303         if (opt_loops) {
304                 depthFirst();                   
305 #ifdef LOOP_DEBUG
306                 resultPass1();                  
307                 fflush(stdout);
308 #endif 
309                 analyseGraph();         
310 #ifdef LOOP_DEBUG
311                 resultPass2(); 
312                 fflush(stdout);
313 #endif 
314                 optimize_loops();
315 #ifdef LOOP_DEBUG
316                 /* resultPass3(); */
317 #endif 
318         }
319    
320
321 #ifdef LOOP_DEBUG
322         printf("Allocating registers  ");
323         fflush(stdout);
324 #endif 
325         interface_regalloc();
326 #ifdef LOOP_DEBUG
327         printf(".");
328         fflush(stdout);
329 #endif 
330         allocate_scratch_registers();
331 #ifdef LOOP_DEBUG
332         printf(".");
333         fflush(stdout); 
334 #endif 
335         local_regalloc();
336 #ifdef LOOP_DEBUG
337         printf(". done\n");
338
339         printf("Generating MCode ... ");
340         fflush(stdout);
341 #endif 
342         gen_mcode();
343 #ifdef LOOP_DEBUG
344         printf("done\n");
345         fflush(stdout);
346 #endif 
347
348         /* intermediate and assembly code listings ********************************/
349                 
350         if (showintermediate)
351                 show_icmd_method();
352         else if (showdisassemble)
353                 disassemble((void*) (m->mcode + dseglen), m->mcodelength - dseglen);
354
355         if (showddatasegment)
356                 dseg_display((void*) (m->mcode));
357
358         /* release dump area */
359
360         dump_release (dumpsize);
361
362         /* measure time */
363
364         if (getcompilingtime) {
365                 stoptime = getcputime();
366                 compilingtime += (stoptime-starttime); 
367                 }
368
369         /* initialize all used classes */
370         /* because of reentrant code global variables are not allowed here        */
371
372         {
373         chain *ul = uninitializedclasses;   /* list of uninitialized classes      */ 
374         classinfo *c;                       /* single class                       */
375
376         while ((c = chain_first(ul)) != NULL) {
377                 chain_remove (ul);
378                 class_init (c);                         /* may again call the compiler        */
379                 }
380         chain_free (ul);
381         }
382
383         intsRestore();    /* enable interrupts again */
384
385         /* return pointer to the methods entry point */
386         
387         return m -> entrypoint;
388
389
390 /* functions for compiler initialisation and finalisation *********************/
391
392 void jit_init ()
393 {
394         int i;
395
396         has_ext_instr_set = ! has_no_x_instr_set();
397
398         for (i = 0; i < 256; i++)
399                 stackreq[i] = 1;
400
401         stackreq[JAVA_NOP]          = 0;
402         stackreq[JAVA_ISTORE]       = 0;
403         stackreq[JAVA_LSTORE]       = 0;
404         stackreq[JAVA_FSTORE]       = 0;
405         stackreq[JAVA_DSTORE]       = 0;
406         stackreq[JAVA_ASTORE]       = 0;
407         stackreq[JAVA_ISTORE_0]     = 0;
408         stackreq[JAVA_ISTORE_1]     = 0;
409         stackreq[JAVA_ISTORE_2]     = 0;
410         stackreq[JAVA_ISTORE_3]     = 0;
411         stackreq[JAVA_LSTORE_0]     = 0;
412         stackreq[JAVA_LSTORE_1]     = 0;
413         stackreq[JAVA_LSTORE_2]     = 0;
414         stackreq[JAVA_LSTORE_3]     = 0;
415         stackreq[JAVA_FSTORE_0]     = 0;
416         stackreq[JAVA_FSTORE_1]     = 0;
417         stackreq[JAVA_FSTORE_2]     = 0;
418         stackreq[JAVA_FSTORE_3]     = 0;
419         stackreq[JAVA_DSTORE_0]     = 0;
420         stackreq[JAVA_DSTORE_1]     = 0;
421         stackreq[JAVA_DSTORE_2]     = 0;
422         stackreq[JAVA_DSTORE_3]     = 0;
423         stackreq[JAVA_ASTORE_0]     = 0;
424         stackreq[JAVA_ASTORE_1]     = 0;
425         stackreq[JAVA_ASTORE_2]     = 0;
426         stackreq[JAVA_ASTORE_3]     = 0;
427         stackreq[JAVA_IASTORE]      = 0;
428         stackreq[JAVA_LASTORE]      = 0;
429         stackreq[JAVA_FASTORE]      = 0;
430         stackreq[JAVA_DASTORE]      = 0;
431         stackreq[JAVA_AASTORE]      = 0;
432         stackreq[JAVA_BASTORE]      = 0;
433         stackreq[JAVA_CASTORE]      = 0;
434         stackreq[JAVA_SASTORE]      = 0;
435         stackreq[JAVA_POP]          = 0;
436         stackreq[JAVA_POP2]         = 0;
437         stackreq[JAVA_IINC]         = 0;
438         stackreq[JAVA_IFEQ]         = 0;
439         stackreq[JAVA_IFNE]         = 0;
440         stackreq[JAVA_IFLT]         = 0;
441         stackreq[JAVA_IFGE]         = 0;
442         stackreq[JAVA_IFGT]         = 0;
443         stackreq[JAVA_IFLE]         = 0;
444         stackreq[JAVA_IF_ICMPEQ]    = 0;
445         stackreq[JAVA_IF_ICMPNE]    = 0;
446         stackreq[JAVA_IF_ICMPLT]    = 0;
447         stackreq[JAVA_IF_ICMPGE]    = 0;
448         stackreq[JAVA_IF_ICMPGT]    = 0;
449         stackreq[JAVA_IF_ICMPLE]    = 0;
450         stackreq[JAVA_IF_ACMPEQ]    = 0;
451         stackreq[JAVA_IF_ACMPNE]    = 0;
452         stackreq[JAVA_GOTO]         = 0;
453         stackreq[JAVA_RET]          = 0;
454         stackreq[JAVA_TABLESWITCH]  = 0;
455         stackreq[ICMD_LOOKUPSWITCH] = 0;
456         stackreq[JAVA_IRETURN]      = 0;
457         stackreq[JAVA_LRETURN]      = 0;
458         stackreq[JAVA_FRETURN]      = 0;
459         stackreq[JAVA_DRETURN]      = 0;
460         stackreq[JAVA_ARETURN]      = 0;
461         stackreq[JAVA_RETURN]       = 0;
462         stackreq[JAVA_PUTSTATIC]    = 0;
463         stackreq[JAVA_PUTFIELD]     = 0;
464         stackreq[JAVA_MONITORENTER] = 0;
465         stackreq[ICMD_MONITOREXIT]  = 0;
466         stackreq[JAVA_WIDE]         = 0;
467         stackreq[JAVA_IFNULL]       = 0;
468         stackreq[JAVA_IFNONNULL]    = 0;
469         stackreq[JAVA_GOTO_W]       = 0;
470         stackreq[JAVA_BREAKPOINT]   = 0;
471
472         stackreq[JAVA_SWAP] = 2;
473         stackreq[JAVA_DUP2] = 2;
474         stackreq[JAVA_DUP_X1] = 3;
475         stackreq[JAVA_DUP_X2] = 4;
476         stackreq[JAVA_DUP2_X1] = 3;
477         stackreq[JAVA_DUP2_X2] = 4;
478         
479         for (i = 0; i < 256; i++) stdopdescriptors[i] = NULL;
480
481         for (i = 0; i < sizeof(stdopdescriptortable)/sizeof(stdopdescriptor); i++) {
482                 
483                 if (stdopdescriptortable[i].isfloat && checkfloats) {
484                         stdopdescriptortable[i].supported = false;
485                         }
486
487                 stdopdescriptors[stdopdescriptortable[i].opcode] = 
488                    &(stdopdescriptortable[i]);
489                 }
490
491         init_exceptions();
492 }
493
494
495 void jit_close()
496 {
497         mcode_close();
498         reg_close();
499 }
500
501
502 /*
503  * These are local overrides for various environment variables in Emacs.
504  * Please do not remove this and leave it at the end of the file, where
505  * Emacs will automagically detect them.
506  * ---------------------------------------------------------------------
507  * Local variables:
508  * mode: c
509  * indent-tabs-mode: t
510  * c-basic-offset: 4
511  * tab-width: 4
512  * End:
513  */