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