1 /* src/vm/jit/jit.c - calls the code generation functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "mm/memory.h"
39 #include "native/native.h"
41 #include "toolbox/logging.h"
43 #include "threads/lock-common.h"
44 #include "threads/threads-common.h"
46 #include "vm/global.h"
47 #include "vm/initialize.h"
49 #include "vm/jit/asmpart.h"
51 #include "vm/jit/cfg.h"
53 #include "vm/jit/codegen-common.h"
54 #include "vm/jit/disass.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/reg.h"
60 #include "vm/jit/show.h"
61 #include "vm/jit/stack.h"
63 #include "vm/jit/allocator/simplereg.h"
64 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
65 # include "vm/jit/allocator/lsra.h"
68 #if defined(ENABLE_SSA)
69 # include "vm/jit/optimizing/lsra.h"
70 # include "vm/jit/optimizing/ssa.h"
73 #if defined(ENABLE_INLINING)
74 # include "vm/jit/inline/inline.h"
77 #include "vm/jit/ir/bytecode.h"
79 #include "vm/jit/loop/analyze.h"
80 #include "vm/jit/loop/graph.h"
81 #include "vm/jit/loop/loop.h"
83 #if defined(ENABLE_IFCONV)
84 # include "vm/jit/optimizing/ifconv.h"
87 #include "vm/jit/optimizing/reorder.h"
89 #if defined(ENABLE_PYTHON)
90 # include "vm/jit/python.h"
93 #include "vm/jit/verify/typecheck.h"
95 #include "vmcore/class.h"
96 #include "vmcore/loader.h"
97 #include "vmcore/method.h"
98 #include "vmcore/options.h"
99 #include "vmcore/rt-timing.h"
100 #include "vmcore/statistics.h"
103 /* debug macros ***************************************************************/
106 #define DEBUG_JIT_COMPILEVERBOSE(x) \
108 if (compileverbose) { \
109 log_message_method(x, m); \
113 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
117 # define TRACECOMPILERCALLS() \
119 if (opt_TraceCompilerCalls) { \
121 log_print("[JIT compiler started: method="); \
128 # define TRACECOMPILERCALLS()
132 /* the ICMD table ************************************************************/
135 #define N(name) name,
140 /* abbreviations for flags */
142 #define PEI ICMDTABLE_PEI
143 #define CALLS ICMDTABLE_CALLS
145 /* some machine dependent values */
150 #define IDIV_CALLS ICMDTABLE_CALLS
153 #if (SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
156 #define LDIV_CALLS ICMDTABLE_CALLS
159 /* include the actual table */
161 icmdtable_entry_t icmd_table[256] = {
162 #include <vm/jit/icmdtable.inc>
169 /* XXX hack until the old "PEI" definition is removed */
173 /* stackelement requirements of Java opcodes **********************************/
175 int stackreq[256] = {
177 1, /* JAVA_ACONST 1 */
178 1, /* JAVA_ICONST_M1 2 */
179 1, /* JAVA_ICONST_0 3 */
180 1, /* JAVA_ICONST_1 4 */
181 1, /* JAVA_ICONST_2 5 */
182 1, /* JAVA_ICONST_3 6 */
183 1, /* JAVA_ICONST_4 7 */
184 1, /* JAVA_ICONST_5 8 */
185 1, /* JAVA_LCONST_0 9 */
186 1, /* JAVA_LCONST_1 10 */
187 1, /* JAVA_FCONST_0 11 */
188 1, /* JAVA_FCONST_1 12 */
189 1, /* JAVA_FCONST_2 13 */
190 1, /* JAVA_DCONST_0 14 */
191 1, /* JAVA_DCONST_1 15 */
192 1, /* JAVA_BIPUSH 16 */
193 1, /* JAVA_SIPUSH 17 */
195 1, /* JAVA_LDC_W 19 */
196 1, /* JAVA_LDC2_W 20 */
197 1, /* JAVA_ILOAD 21 */
198 1, /* JAVA_LLOAD 22 */
199 1, /* JAVA_FLOAD 23 */
200 1, /* JAVA_DLOAD 24 */
201 1, /* JAVA_ALOAD 25 */
202 1, /* JAVA_ILOAD_0 26 */
203 1, /* JAVA_ILOAD_1 27 */
204 1, /* JAVA_ILOAD_2 28 */
205 1, /* JAVA_ILOAD_3 29 */
206 1, /* JAVA_LLOAD_0 30 */
207 1, /* JAVA_LLOAD_1 31 */
208 1, /* JAVA_LLOAD_2 32 */
209 1, /* JAVA_LLOAD_3 33 */
210 1, /* JAVA_FLOAD_0 34 */
211 1, /* JAVA_FLOAD_1 35 */
212 1, /* JAVA_FLOAD_2 36 */
213 1, /* JAVA_FLOAD_3 37 */
214 1, /* JAVA_DLOAD_0 38 */
215 1, /* JAVA_DLOAD_1 39 */
216 1, /* JAVA_DLOAD_2 40 */
217 1, /* JAVA_DLOAD_3 41 */
218 1, /* JAVA_ALOAD_0 42 */
219 1, /* JAVA_ALOAD_1 43 */
220 1, /* JAVA_ALOAD_2 44 */
221 1, /* JAVA_ALOAD_3 45 */
222 1, /* JAVA_IALOAD 46 */
223 1, /* JAVA_LALOAD 47 */
224 1, /* JAVA_FALOAD 48 */
225 1, /* JAVA_DALOAD 49 */
226 1, /* JAVA_AALOAD 50 */
227 1, /* JAVA_BALOAD 51 */
228 1, /* JAVA_CALOAD 52 */
229 1, /* JAVA_SALOAD 53 */
230 0, /* JAVA_ISTORE 54 */
231 0, /* JAVA_LSTORE 55 */
232 0, /* JAVA_FSTORE 56 */
233 0, /* JAVA_DSTORE 57 */
234 0, /* JAVA_ASTORE 58 */
235 0, /* JAVA_ISTORE_0 59 */
236 0, /* JAVA_ISTORE_1 60 */
237 0, /* JAVA_ISTORE_2 61 */
238 0, /* JAVA_ISTORE_3 62 */
239 0, /* JAVA_LSTORE_0 63 */
240 0, /* JAVA_LSTORE_1 64 */
241 0, /* JAVA_LSTORE_2 65 */
242 0, /* JAVA_LSTORE_3 66 */
243 0, /* JAVA_FSTORE_0 67 */
244 0, /* JAVA_FSTORE_1 68 */
245 0, /* JAVA_FSTORE_2 69 */
246 0, /* JAVA_FSTORE_3 70 */
247 0, /* JAVA_DSTORE_0 71 */
248 0, /* JAVA_DSTORE_1 72 */
249 0, /* JAVA_DSTORE_2 73 */
250 0, /* JAVA_DSTORE_3 74 */
251 0, /* JAVA_ASTORE_0 75 */
252 0, /* JAVA_ASTORE_1 76 */
253 0, /* JAVA_ASTORE_2 77 */
254 0, /* JAVA_ASTORE_3 78 */
255 0, /* JAVA_IASTORE 79 */
256 0, /* JAVA_LASTORE 80 */
257 0, /* JAVA_FASTORE 81 */
258 0, /* JAVA_DASTORE 82 */
259 0, /* JAVA_AASTORE 83 */
260 0, /* JAVA_BASTORE 84 */
261 0, /* JAVA_CASTORE 85 */
262 0, /* JAVA_SASTORE 86 */
264 0, /* JAVA_POP2 88 */
266 1+3, /* JAVA_DUP_X1 90 */
267 2+4, /* JAVA_DUP_X2 91 */
268 2, /* JAVA_DUP2 92 */
269 2+5, /* JAVA_DUP2_X1 93 */
270 3+6, /* JAVA_DUP2_X2 94 */
271 1+2, /* JAVA_SWAP 95 */
272 1, /* JAVA_IADD 96 */
273 1, /* JAVA_LADD 97 */
274 1, /* JAVA_FADD 98 */
275 1, /* JAVA_DADD 99 */
276 1, /* JAVA_ISUB 100 */
277 1, /* JAVA_LSUB 101 */
278 1, /* JAVA_FSUB 102 */
279 1, /* JAVA_DSUB 103 */
280 1, /* JAVA_IMUL 104 */
281 1, /* JAVA_LMUL 105 */
282 1, /* JAVA_FMUL 106 */
283 1, /* JAVA_DMUL 107 */
284 1, /* JAVA_IDIV 108 */
285 1, /* JAVA_LDIV 109 */
286 1, /* JAVA_FDIV 110 */
287 1, /* JAVA_DDIV 111 */
288 1, /* JAVA_IREM 112 */
289 1, /* JAVA_LREM 113 */
290 1, /* JAVA_FREM 114 */
291 1, /* JAVA_DREM 115 */
292 1, /* JAVA_INEG 116 */
293 1, /* JAVA_LNEG 117 */
294 1, /* JAVA_FNEG 118 */
295 1, /* JAVA_DNEG 119 */
296 1, /* JAVA_ISHL 120 */
297 1, /* JAVA_LSHL 121 */
298 1, /* JAVA_ISHR 122 */
299 1, /* JAVA_LSHR 123 */
300 1, /* JAVA_IUSHR 124 */
301 1, /* JAVA_LUSHR 125 */
302 1, /* JAVA_IAND 126 */
303 1, /* JAVA_LAND 127 */
304 1, /* JAVA_IOR 128 */
305 1, /* JAVA_LOR 129 */
306 1, /* JAVA_IXOR 130 */
307 1, /* JAVA_LXOR 131 */
308 0, /* JAVA_IINC 132 */
309 1, /* JAVA_I2L 133 */
310 1, /* JAVA_I2F 134 */
311 1, /* JAVA_I2D 135 */
312 1, /* JAVA_L2I 136 */
313 1, /* JAVA_L2F 137 */
314 1, /* JAVA_L2D 138 */
315 1, /* JAVA_F2I 139 */
316 1, /* JAVA_F2L 140 */
317 1, /* JAVA_F2D 141 */
318 1, /* JAVA_D2I 142 */
319 1, /* JAVA_D2L 143 */
320 1, /* JAVA_D2F 144 */
321 1, /* JAVA_INT2BYTE 145 */
322 1, /* JAVA_INT2CHAR 146 */
323 1, /* JAVA_INT2SHORT 147 */
324 1, /* JAVA_LCMP 148 */
325 1, /* JAVA_FCMPL 149 */
326 1, /* JAVA_FCMPG 150 */
327 1, /* JAVA_DCMPL 151 */
328 1, /* JAVA_DCMPG 152 */
329 0, /* JAVA_IFEQ 153 */
330 0, /* JAVA_IFNE 154 */
331 0, /* JAVA_IFLT 155 */
332 0, /* JAVA_IFGE 156 */
333 0, /* JAVA_IFGT 157 */
334 0, /* JAVA_IFLE 158 */
335 0, /* JAVA_IF_ICMPEQ 159 */
336 0, /* JAVA_IF_ICMPNE 160 */
337 0, /* JAVA_IF_ICMPLT 161 */
338 0, /* JAVA_IF_ICMPGE 162 */
339 0, /* JAVA_IF_ICMPGT 163 */
340 0, /* JAVA_IF_ICMPLE 164 */
341 0, /* JAVA_IF_ACMPEQ 165 */
342 0, /* JAVA_IF_ACMPNE 166 */
343 0, /* JAVA_GOTO 167 */
344 1, /* JAVA_JSR 168 */
345 0, /* JAVA_RET 169 */
346 0, /* JAVA_TABLESWITCH 170 */
347 0, /* JAVA_LOOKUPSWITCH 171 */
348 0, /* JAVA_IRETURN 172 */
349 0, /* JAVA_LRETURN 173 */
350 0, /* JAVA_FRETURN 174 */
351 0, /* JAVA_DRETURN 175 */
352 0, /* JAVA_ARETURN 176 */
353 0, /* JAVA_RETURN 177 */
354 1, /* JAVA_GETSTATIC 178 */
355 0, /* JAVA_PUTSTATIC 179 */
356 1, /* JAVA_GETFIELD 180 */
357 0, /* JAVA_PUTFIELD 181 */
358 1, /* JAVA_INVOKEVIRTUAL 182 */
359 1, /* JAVA_INVOKESPECIAL 183 */
360 1, /* JAVA_INVOKESTATIC 184 */
361 1, /* JAVA_INVOKEINTERFACE 185 */
362 1, /* JAVA_UNDEF186 186 */
363 1, /* JAVA_NEW 187 */
364 1, /* JAVA_NEWARRAY 188 */
365 1, /* JAVA_ANEWARRAY 189 */
366 1, /* JAVA_ARRAYLENGTH 190 */
367 1, /* JAVA_ATHROW 191 */
368 1, /* JAVA_CHECKCAST 192 */
369 1, /* JAVA_INSTANCEOF 193 */
370 0, /* JAVA_MONITORENTER 194 */
371 0, /* JAVA_MONITOREXIT 195 */
372 0, /* JAVA_WIDE 196 */
373 1, /* JAVA_MULTIANEWARRAY 197 */
374 0, /* JAVA_IFNULL 198 */
375 0, /* JAVA_IFNONNULL 199 */
376 0, /* JAVA_GOTO_W 200 */
377 1, /* JAVA_JSR_W 201 */
378 0, /* JAVA_BREAKPOINT 202 */
379 1, /* JAVA_UNDEF203 203 */
380 1, /* JAVA_UNDEF204 204 */
381 1, /* JAVA_UNDEF205 205 */
382 1, /* JAVA_UNDEF206 206 */
383 1, /* JAVA_UNDEF207 207 */
384 1, /* JAVA_UNDEF208 208 */
385 1, /* JAVA_UNDEF209 209 */
386 1, /* JAVA_UNDEF210 210 */
387 1, /* JAVA_UNDEF211 211 */
388 1, /* JAVA_UNDEF212 212 */
389 1, /* JAVA_UNDEF213 213 */
390 1, /* JAVA_UNDEF214 214 */
391 1, /* JAVA_UNDEF215 215 */
392 1, /* JAVA_UNDEF216 216 */
393 1, /* JAVA_UNDEF217 217 */
394 1, /* JAVA_UNDEF218 218 */
395 1, /* JAVA_UNDEF219 219 */
396 1, /* JAVA_UNDEF220 220 */
397 1, /* JAVA_UNDEF221 221 */
398 1, /* JAVA_UNDEF222 222 */
399 1, /* JAVA_UNDEF223 223 */
400 1, /* JAVA_UNDEF224 224 */
401 1, /* JAVA_UNDEF225 225 */
402 1, /* JAVA_UNDEF226 226 */
403 1, /* JAVA_UNDEF227 227 */
404 1, /* JAVA_UNDEF228 228 */
405 1, /* JAVA_UNDEF229 229 */
406 1, /* JAVA_UNDEF230 230 */
407 1, /* JAVA_UNDEF231 231 */
408 1, /* JAVA_UNDEF232 232 */
409 1, /* JAVA_UNDEF233 233 */
410 1, /* JAVA_UNDEF234 234 */
411 1, /* JAVA_UNDEF235 235 */
412 1, /* JAVA_UNDEF236 236 */
413 1, /* JAVA_UNDEF237 237 */
414 1, /* JAVA_UNDEF238 238 */
415 1, /* JAVA_UNDEF239 239 */
416 1, /* JAVA_UNDEF240 240 */
417 1, /* JAVA_UNDEF241 241 */
418 1, /* JAVA_UNDEF242 242 */
419 1, /* JAVA_UNDEF243 243 */
420 1, /* JAVA_UNDEF244 244 */
421 1, /* JAVA_UNDEF245 245 */
422 1, /* JAVA_UNDEF246 246 */
423 1, /* JAVA_UNDEF247 247 */
424 1, /* JAVA_UNDEF248 248 */
425 1, /* JAVA_UNDEF249 249 */
426 1, /* JAVA_UNDEF250 250 */
427 1, /* JAVA_UNDEF251 251 */
428 1, /* JAVA_UNDEF252 252 */
429 1, /* JAVA_UNDEF253 253 */
430 1, /* JAVA_UNDEF254 254 */
431 1, /* JAVA_UNDEF255 255 */
435 /* size in bytes of Java opcodes **********************************************/
437 int jcommandsize[256] = {
440 1, /* JAVA_ACONST_NULL 1 */
441 1, /* JAVA_ICONST_M1 2 */
442 1, /* JAVA_ICONST_0 3 */
443 1, /* JAVA_ICONST_1 4 */
444 1, /* JAVA_ICONST_2 5 */
445 1, /* JAVA_ICONST_3 6 */
446 1, /* JAVA_ICONST_4 7 */
447 1, /* JAVA_ICONST_5 8 */
448 1, /* JAVA_LCONST_0 9 */
449 1, /* JAVA_LCONST_1 10 */
450 1, /* JAVA_FCONST_0 11 */
451 1, /* JAVA_FCONST_1 12 */
452 1, /* JAVA_FCONST_2 13 */
453 1, /* JAVA_DCONST_0 14 */
454 1, /* JAVA_DCONST_1 15 */
455 2, /* JAVA_BIPUSH 16 */
456 3, /* JAVA_SIPUSH 17 */
457 2, /* JAVA_LDC1 18 */
458 3, /* JAVA_LDC2 19 */
459 3, /* JAVA_LDC2W 20 */
460 2, /* JAVA_ILOAD 21 */
461 2, /* JAVA_LLOAD 22 */
462 2, /* JAVA_FLOAD 23 */
463 2, /* JAVA_DLOAD 24 */
464 2, /* JAVA_ALOAD 25 */
465 1, /* JAVA_ILOAD_0 26 */
466 1, /* JAVA_ILOAD_1 27 */
467 1, /* JAVA_ILOAD_2 28 */
468 1, /* JAVA_ILOAD_3 29 */
469 1, /* JAVA_LLOAD_0 30 */
470 1, /* JAVA_LLOAD_1 31 */
471 1, /* JAVA_LLOAD_2 32 */
472 1, /* JAVA_LLOAD_3 33 */
473 1, /* JAVA_FLOAD_0 34 */
474 1, /* JAVA_FLOAD_1 35 */
475 1, /* JAVA_FLOAD_2 36 */
476 1, /* JAVA_FLOAD_3 37 */
477 1, /* JAVA_DLOAD_0 38 */
478 1, /* JAVA_DLOAD_1 39 */
479 1, /* JAVA_DLOAD_2 40 */
480 1, /* JAVA_DLOAD_3 41 */
481 1, /* JAVA_ALOAD_0 42 */
482 1, /* JAVA_ALOAD_1 43 */
483 1, /* JAVA_ALOAD_2 44 */
484 1, /* JAVA_ALOAD_3 45 */
485 1, /* JAVA_IALOAD 46 */
486 1, /* JAVA_LALOAD 47 */
487 1, /* JAVA_FALOAD 48 */
488 1, /* JAVA_DALOAD 49 */
489 1, /* JAVA_AALOAD 50 */
490 1, /* JAVA_BALOAD 51 */
491 1, /* JAVA_CALOAD 52 */
492 1, /* JAVA_SALOAD 53 */
493 2, /* JAVA_ISTORE 54 */
494 2, /* JAVA_LSTORE 55 */
495 2, /* JAVA_FSTORE 56 */
496 2, /* JAVA_DSTORE 57 */
497 2, /* JAVA_ASTORE 58 */
498 1, /* JAVA_ISTORE_0 59 */
499 1, /* JAVA_ISTORE_1 60 */
500 1, /* JAVA_ISTORE_2 61 */
501 1, /* JAVA_ISTORE_3 62 */
502 1, /* JAVA_LSTORE_0 63 */
503 1, /* JAVA_LSTORE_1 64 */
504 1, /* JAVA_LSTORE_2 65 */
505 1, /* JAVA_LSTORE_3 66 */
506 1, /* JAVA_FSTORE_0 67 */
507 1, /* JAVA_FSTORE_1 68 */
508 1, /* JAVA_FSTORE_2 69 */
509 1, /* JAVA_FSTORE_3 70 */
510 1, /* JAVA_DSTORE_0 71 */
511 1, /* JAVA_DSTORE_1 72 */
512 1, /* JAVA_DSTORE_2 73 */
513 1, /* JAVA_DSTORE_3 74 */
514 1, /* JAVA_ASTORE_0 75 */
515 1, /* JAVA_ASTORE_1 76 */
516 1, /* JAVA_ASTORE_2 77 */
517 1, /* JAVA_ASTORE_3 78 */
518 1, /* JAVA_IASTORE 79 */
519 1, /* JAVA_LASTORE 80 */
520 1, /* JAVA_FASTORE 81 */
521 1, /* JAVA_DASTORE 82 */
522 1, /* JAVA_AASTORE 83 */
523 1, /* JAVA_BASTORE 84 */
524 1, /* JAVA_CASTORE 85 */
525 1, /* JAVA_SASTORE 86 */
527 1, /* JAVA_POP2 88 */
529 1, /* JAVA_DUP_X1 90 */
530 1, /* JAVA_DUP_X2 91 */
531 1, /* JAVA_DUP2 92 */
532 1, /* JAVA_DUP2_X1 93 */
533 1, /* JAVA_DUP2_X2 94 */
534 1, /* JAVA_SWAP 95 */
535 1, /* JAVA_IADD 96 */
536 1, /* JAVA_LADD 97 */
537 1, /* JAVA_FADD 98 */
538 1, /* JAVA_DADD 99 */
539 1, /* JAVA_ISUB 100 */
540 1, /* JAVA_LSUB 101 */
541 1, /* JAVA_FSUB 102 */
542 1, /* JAVA_DSUB 103 */
543 1, /* JAVA_IMUL 104 */
544 1, /* JAVA_LMUL 105 */
545 1, /* JAVA_FMUL 106 */
546 1, /* JAVA_DMUL 107 */
547 1, /* JAVA_IDIV 108 */
548 1, /* JAVA_LDIV 109 */
549 1, /* JAVA_FDIV 110 */
550 1, /* JAVA_DDIV 111 */
551 1, /* JAVA_IREM 112 */
552 1, /* JAVA_LREM 113 */
553 1, /* JAVA_FREM 114 */
554 1, /* JAVA_DREM 115 */
555 1, /* JAVA_INEG 116 */
556 1, /* JAVA_LNEG 117 */
557 1, /* JAVA_FNEG 118 */
558 1, /* JAVA_DNEG 119 */
559 1, /* JAVA_ISHL 120 */
560 1, /* JAVA_LSHL 121 */
561 1, /* JAVA_ISHR 122 */
562 1, /* JAVA_LSHR 123 */
563 1, /* JAVA_IUSHR 124 */
564 1, /* JAVA_LUSHR 125 */
565 1, /* JAVA_IAND 126 */
566 1, /* JAVA_LAND 127 */
567 1, /* JAVA_IOR 128 */
568 1, /* JAVA_LOR 129 */
569 1, /* JAVA_IXOR 130 */
570 1, /* JAVA_LXOR 131 */
571 3, /* JAVA_IINC 132 */
572 1, /* JAVA_I2L 133 */
573 1, /* JAVA_I2F 134 */
574 1, /* JAVA_I2D 135 */
575 1, /* JAVA_L2I 136 */
576 1, /* JAVA_L2F 137 */
577 1, /* JAVA_L2D 138 */
578 1, /* JAVA_F2I 139 */
579 1, /* JAVA_F2L 140 */
580 1, /* JAVA_F2D 141 */
581 1, /* JAVA_D2I 142 */
582 1, /* JAVA_D2L 143 */
583 1, /* JAVA_D2F 144 */
584 1, /* JAVA_INT2BYTE 145 */
585 1, /* JAVA_INT2CHAR 146 */
586 1, /* JAVA_INT2SHORT 147 */
587 1, /* JAVA_LCMP 148 */
588 1, /* JAVA_FCMPL 149 */
589 1, /* JAVA_FCMPG 150 */
590 1, /* JAVA_DCMPL 151 */
591 1, /* JAVA_DCMPG 152 */
592 3, /* JAVA_IFEQ 153 */
593 3, /* JAVA_IFNE 154 */
594 3, /* JAVA_IFLT 155 */
595 3, /* JAVA_IFGE 156 */
596 3, /* JAVA_IFGT 157 */
597 3, /* JAVA_IFLE 158 */
598 3, /* JAVA_IF_ICMPEQ 159 */
599 3, /* JAVA_IF_ICMPNE 160 */
600 3, /* JAVA_IF_ICMPLT 161 */
601 3, /* JAVA_IF_ICMPGE 162 */
602 3, /* JAVA_IF_ICMPGT 163 */
603 3, /* JAVA_IF_ICMPLE 164 */
604 3, /* JAVA_IF_ACMPEQ 165 */
605 3, /* JAVA_IF_ACMPNE 166 */
606 3, /* JAVA_GOTO 167 */
607 3, /* JAVA_JSR 168 */
608 2, /* JAVA_RET 169 */
609 0, /* JAVA_TABLESWITCH 170 */ /* variable length */
610 0, /* JAVA_LOOKUPSWITCH 171 */ /* variable length */
611 1, /* JAVA_IRETURN 172 */
612 1, /* JAVA_LRETURN 173 */
613 1, /* JAVA_FRETURN 174 */
614 1, /* JAVA_DRETURN 175 */
615 1, /* JAVA_ARETURN 176 */
616 1, /* JAVA_RETURN 177 */
617 3, /* JAVA_GETSTATIC 178 */
618 3, /* JAVA_PUTSTATIC 179 */
619 3, /* JAVA_GETFIELD 180 */
620 3, /* JAVA_PUTFIELD 181 */
621 3, /* JAVA_INVOKEVIRTUAL 182 */
622 3, /* JAVA_INVOKESPECIAL 183 */
623 3, /* JAVA_INVOKESTATIC 184 */
624 5, /* JAVA_INVOKEINTERFACE 185 */
626 3, /* JAVA_NEW 187 */
627 2, /* JAVA_NEWARRAY 188 */
628 3, /* JAVA_ANEWARRAY 189 */
629 1, /* JAVA_ARRAYLENGTH 190 */
630 1, /* JAVA_ATHROW 191 */
631 3, /* JAVA_CHECKCAST 192 */
632 3, /* JAVA_INSTANCEOF 193 */
633 1, /* JAVA_MONITORENTER 194 */
634 1, /* JAVA_MONITOREXIT 195 */
635 0, /* JAVA_WIDE 196 */ /* variable length */
636 4, /* JAVA_MULTIANEWARRAY 197 */
637 3, /* JAVA_IFNULL 198 */
638 3, /* JAVA_IFNONNULL 199 */
639 5, /* JAVA_GOTO_W 200 */
640 5, /* JAVA_JSR_W 201 */
641 1, /* JAVA_BREAKPOINT 202 */
678 1,1,1,1,1,1,1,1,1,1,
683 /* Java opcode names *********************************************************/
685 char *opcode_names[256] = {
688 "ICONST_M1 ", /* ICONST_M1 2 */
689 "ICONST_0 ", /* ICONST_0 3 */
690 "ICONST_1 ", /* ICONST_1 4 */
691 "ICONST_2 ", /* ICONST_2 5 */
692 "ICONST_3 ", /* ICONST_3 6 */
693 "ICONST_4 ", /* ICONST_4 7 */
694 "ICONST_5 ", /* ICONST_5 8 */
695 "LCONST_0 ", /* LCONST_0 9 */
696 "LCONST_1 ", /* LCONST_1 10 */
697 "FCONST_0 ", /* FCONST_0 11 */
698 "FCONST_1 ", /* FCONST_1 12 */
699 "FCONST_2 ", /* FCONST_2 13 */
700 "DCONST_0 ", /* DCONST_0 14 */
701 "DCONST_1 ", /* DCONST_1 15 */
702 "BIPUSH ", /* BIPUSH 16 */
703 "SIPUSH ", /* SIPUSH 17 */
705 "LDC_W ", /* LDC_W 19 */
706 "LDC2_W ", /* LDC2_W 20 */
712 "ILOAD_0 ", /* ILOAD_0 26 */
713 "ILOAD_1 ", /* ILOAD_1 27 */
714 "ILOAD_2 ", /* ILOAD_2 28 */
715 "ILOAD_3 ", /* ILOAD_3 29 */
716 "LLOAD_0 ", /* LLOAD_0 30 */
717 "LLOAD_1 ", /* LLOAD_1 31 */
718 "LLOAD_2 ", /* LLOAD_2 32 */
719 "LLOAD_3 ", /* LLOAD_3 33 */
720 "FLOAD_0 ", /* FLOAD_0 34 */
721 "FLOAD_1 ", /* FLOAD_1 35 */
722 "FLOAD_2 ", /* FLOAD_2 36 */
723 "FLOAD_3 ", /* FLOAD_3 37 */
724 "DLOAD_0 ", /* DLOAD_0 38 */
725 "DLOAD_1 ", /* DLOAD_1 39 */
726 "DLOAD_2 ", /* DLOAD_2 40 */
727 "DLOAD_3 ", /* DLOAD_3 41 */
728 "ALOAD_0 ", /* ALOAD_0 42 */
729 "ALOAD_1 ", /* ALOAD_1 43 */
730 "ALOAD_2 ", /* ALOAD_2 44 */
731 "ALOAD_3 ", /* ALOAD_3 45 */
745 "ISTORE_0 ", /* ISTORE_0 59 */
746 "ISTORE_1 ", /* ISTORE_1 60 */
747 "ISTORE_2 ", /* ISTORE_2 61 */
748 "ISTORE_3 ", /* ISTORE_3 62 */
749 "LSTORE_0 ", /* LSTORE_0 63 */
750 "LSTORE_1 ", /* LSTORE_1 64 */
751 "LSTORE_2 ", /* LSTORE_2 65 */
752 "LSTORE_3 ", /* LSTORE_3 66 */
753 "FSTORE_0 ", /* FSTORE_0 67 */
754 "FSTORE_1 ", /* FSTORE_1 68 */
755 "FSTORE_2 ", /* FSTORE_2 69 */
756 "FSTORE_3 ", /* FSTORE_3 70 */
757 "DSTORE_0 ", /* DSTORE_0 71 */
758 "DSTORE_1 ", /* DSTORE_1 72 */
759 "DSTORE_2 ", /* DSTORE_2 73 */
760 "DSTORE_3 ", /* DSTORE_3 74 */
761 "ASTORE_0 ", /* ASTORE_0 75 */
762 "ASTORE_1 ", /* ASTORE_1 76 */
763 "ASTORE_2 ", /* ASTORE_2 77 */
764 "ASTORE_3 ", /* ASTORE_3 78 */
831 "INT2BYTE ", /* 145 */
832 "INT2CHAR ", /* 146 */
833 "INT2SHORT ", /* 147 */
845 "IF_ICMPEQ ", /* 159 */
846 "IF_ICMPNE ", /* 160 */
847 "IF_ICMPLT ", /* 161 */
848 "IF_ICMPGE ", /* 162 */
849 "IF_ICMPGT ", /* 163 */
850 "IF_ICMPLE ", /* 164 */
851 "IF_ACMPEQ ", /* 165 */
852 "IF_ACMPNE ", /* 166 */
856 "TABLESWITCH ", /* 170 */
857 "LOOKUPSWITCH ", /* 171 */
858 "IRETURN ", /* 172 */
859 "LRETURN ", /* 173 */
860 "FRETURN ", /* 174 */
861 "DRETURN ", /* 175 */
862 "ARETURN ", /* 176 */
864 "GETSTATIC ", /* 178 */
865 "PUTSTATIC ", /* 179 */
866 "GETFIELD ", /* 180 */
867 "PUTFIELD ", /* 181 */
868 "INVOKEVIRTUAL ", /* 182 */
869 "INVOKESPECIAL ", /* 183 */
870 "INVOKESTATIC ", /* 184 */
871 "INVOKEINTERFACE", /* 185 */
872 "UNDEF186 ", /* 186 */
874 "NEWARRAY ", /* 188 */
875 "ANEWARRAY ", /* 189 */
876 "ARRAYLENGTH ", /* 190 */
878 "CHECKCAST ", /* 192 */
879 "INSTANCEOF ", /* 193 */
880 "MONITORENTER ", /* 194 */
881 "MONITOREXIT ", /* 195 */
882 "WIDE ", /* WIDE 196 */
883 "MULTIANEWARRAY ", /* 197 */
885 "IFNONNULL ", /* 199 */
886 "GOTO_W ", /* GOTO_W 200 */
887 "JSR_W ", /* JSR_W 201 */
888 "BREAKPOINT ", /* BREAKPOINT 202 */
890 "UNDEF203", "UNDEF204", "UNDEF205",
891 "UNDEF206", "UNDEF207", "UNDEF208", "UNDEF209", "UNDEF210",
892 "UNDEF211", "UNDEF212", "UNDEF213", "UNDEF214", "UNDEF215",
893 "UNDEF216", "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
894 "UNDEF221", "UNDEF222", "UNDEF223", "UNDEF224", "UNDEF225",
895 "UNDEF226", "UNDEF227", "UNDEF228", "UNDEF229", "UNDEF230",
896 "UNDEF231", "UNDEF232", "UNDEF233", "UNDEF234", "UNDEF235",
897 "UNDEF236", "UNDEF237", "UNDEF238", "UNDEF239", "UNDEF240",
898 "UNDEF241", "UNDEF242", "UNDEF243", "UNDEF244", "UNDEF245",
899 "UNDEF246", "UNDEF247", "UNDEF248", "UNDEF249", "UNDEF250",
900 "UNDEF251", "UNDEF252", "UNDEF253", "UNDEF254", "UNDEF255"
904 /* jit_init ********************************************************************
906 Initializes the JIT subsystem.
908 *******************************************************************************/
912 #if defined(ENABLE_JIT)
913 /* initialize stack analysis subsystem */
918 /* initialize show subsystem */
924 /* initialize codegen subsystem */
928 /* initialize code subsystem */
932 /* Machine dependent initialization. */
934 #if defined(ENABLE_JIT)
935 # if defined(ENABLE_INTRP)
947 /* jit_close *******************************************************************
949 Close the JIT subsystem.
951 *******************************************************************************/
959 /* dummy function, used when there is no JavaVM code available */
961 static u1 *do_nothing_function(void)
967 /* jit_jitdata_new *************************************************************
969 Allocates and initalizes a new jitdata structure.
971 *******************************************************************************/
973 jitdata *jit_jitdata_new(methodinfo *m)
978 /* allocate jitdata structure and fill it */
983 jd->cd = DNEW(codegendata);
984 jd->rd = DNEW(registerdata);
985 #if defined(ENABLE_LOOP)
986 jd->ld = DNEW(loopdata);
989 /* Allocate codeinfo memory from the heap as we need to keep them. */
991 code = code_codeinfo_new(m);
993 /* Set codeinfo flags. */
995 #if defined(ENABLE_THREADS)
996 if (checksync && (m->flags & ACC_SYNCHRONIZED))
997 code_flag_synchronized(code);
999 if (checksync && (m->flags & ACC_SYNCHRONIZED))
1000 code_unflag_leafmethod(code);
1003 code_flag_leafmethod(code);
1005 /* initialize variables */
1009 jd->exceptiontable = NULL;
1010 jd->exceptiontablelength = 0;
1011 jd->returncount = 0;
1012 jd->branchtoentry = false;
1013 jd->branchtoend = false;
1014 jd->returncount = 0;
1015 jd->returnblock = NULL;
1016 jd->maxlocals = m->maxlocals;
1022 /* jit_compile *****************************************************************
1024 Translates one method to machine code.
1026 *******************************************************************************/
1028 static u1 *jit_compile_intern(jitdata *jd);
1030 u1 *jit_compile(methodinfo *m)
1036 STATISTICS(count_jit_calls++);
1038 /* Initialize the static function's class. */
1040 /* ATTENTION: This MUST be done before the method lock is aquired,
1041 otherwise we could run into a deadlock with <clinit>'s that
1042 call static methods of it's own class. */
1044 if ((m->flags & ACC_STATIC) && !(m->class->state & CLASS_INITIALIZED)) {
1045 #if !defined(NDEBUG)
1047 log_message_class("Initialize class ", m->class);
1050 if (!initialize_class(m->class))
1053 /* check if the method has been compiled during initialization */
1055 if ((m->code != NULL) && (m->code->entrypoint != NULL))
1056 return m->code->entrypoint;
1059 /* enter a monitor on the method */
1061 LOCK_MONITOR_ENTER(m);
1063 /* if method has been already compiled return immediately */
1065 if (m->code != NULL) {
1066 LOCK_MONITOR_EXIT(m);
1068 assert(m->code->entrypoint);
1069 return m->code->entrypoint;
1072 TRACECOMPILERCALLS();
1074 STATISTICS(count_methods++);
1076 #if defined(ENABLE_STATISTICS)
1079 if (opt_getcompilingtime)
1080 compilingtime_start();
1083 /* mark start of dump memory area */
1085 dumpsize = dump_size();
1087 /* create jitdata structure */
1089 jd = jit_jitdata_new(m);
1091 /* set the flags for the current JIT run */
1093 jd->flags = JITDATA_FLAG_PARSE;
1095 #if defined(ENABLE_VERIFIER)
1097 jd->flags |= JITDATA_FLAG_VERIFY;
1100 #if defined(ENABLE_PROFILING)
1102 jd->flags |= JITDATA_FLAG_INSTRUMENT;
1105 #if defined(ENABLE_IFCONV)
1107 jd->flags |= JITDATA_FLAG_IFCONV;
1110 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
1111 if (opt_inlining && opt_inline_debug_all)
1112 jd->flags |= JITDATA_FLAG_INLINE;
1115 if (opt_showintermediate)
1116 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
1118 if (opt_showdisassemble)
1119 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
1121 if (opt_verbosecall)
1122 jd->flags |= JITDATA_FLAG_VERBOSECALL;
1124 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
1126 jd->flags |= JITDATA_FLAG_COUNTDOWN;
1129 #if defined(ENABLE_JIT)
1130 # if defined(ENABLE_INTRP)
1133 /* initialize the register allocator */
1139 /* setup the codegendata memory */
1143 /* now call internal compile function */
1145 r = jit_compile_intern(jd);
1148 /* We had an exception! Finish stuff here if necessary. */
1150 /* release codeinfo */
1152 code_codeinfo_free(jd->code);
1154 #if defined(ENABLE_PROFILING)
1155 /* Release memory for basic block profiling information. */
1157 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
1158 if (jd->code->bbfrequency != NULL)
1159 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
1163 DEBUG_JIT_COMPILEVERBOSE("Running: ");
1166 /* release dump area */
1168 dump_release(dumpsize);
1170 #if defined(ENABLE_STATISTICS)
1173 if (opt_getcompilingtime)
1174 compilingtime_stop();
1177 /* leave the monitor */
1179 LOCK_MONITOR_EXIT(m);
1181 /* return pointer to the methods entry point */
1187 /* jit_recompile ***************************************************************
1189 Recompiles a Java method.
1191 *******************************************************************************/
1193 u1 *jit_recompile(methodinfo *m)
1200 /* check for max. optimization level */
1202 optlevel = (m->code) ? m->code->optlevel : 0;
1205 if (optlevel == 1) {
1206 /* log_message_method("not recompiling: ", m); */
1211 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
1213 STATISTICS(count_jit_calls++);
1215 #if defined(ENABLE_STATISTICS)
1218 if (opt_getcompilingtime)
1219 compilingtime_start();
1222 /* mark start of dump memory area */
1224 dumpsize = dump_size();
1226 /* create jitdata structure */
1228 jd = jit_jitdata_new(m);
1230 /* set the current optimization level to the previous one plus 1 */
1232 jd->code->optlevel = optlevel + 1;
1234 /* get the optimization flags for the current JIT run */
1236 #if defined(ENABLE_VERIFIER)
1237 jd->flags |= JITDATA_FLAG_VERIFY;
1240 /* jd->flags |= JITDATA_FLAG_REORDER; */
1241 if (opt_showintermediate)
1242 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
1243 if (opt_showdisassemble)
1244 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
1245 if (opt_verbosecall)
1246 jd->flags |= JITDATA_FLAG_VERBOSECALL;
1248 #if defined(ENABLE_INLINING)
1250 jd->flags |= JITDATA_FLAG_INLINE;
1253 #if defined(ENABLE_JIT)
1254 # if defined(ENABLE_INTRP)
1257 /* initialize the register allocator */
1262 /* setup the codegendata memory */
1266 /* now call internal compile function */
1268 r = jit_compile_intern(jd);
1271 /* We had an exception! Finish stuff here if necessary. */
1273 /* release codeinfo */
1275 code_codeinfo_free(jd->code);
1278 /* release dump area */
1280 dump_release(dumpsize);
1282 #if defined(ENABLE_STATISTICS)
1285 if (opt_getcompilingtime)
1286 compilingtime_stop();
1289 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
1291 /* return pointer to the methods entry point */
1297 /* jit_compile_intern **********************************************************
1299 Static internal function which does the actual compilation.
1301 *******************************************************************************/
1303 static u1 *jit_compile_intern(jitdata *jd)
1309 #if defined(ENABLE_RT_TIMING)
1310 struct timespec time_start,time_checks,time_parse,time_stack,
1311 time_typecheck,time_loop,time_ifconv,time_alloc,
1315 RT_TIMING_GET_TIME(time_start);
1317 /* get required compiler data */
1319 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1326 #if defined(ENABLE_DEBUG_FILTER)
1327 show_filters_apply(jd->m);
1330 /* Handle native methods and create a native stub. */
1332 if (m->flags & ACC_NATIVE) {
1335 f = native_method_resolve(m);
1340 code = codegen_generate_stub_native(m, f);
1342 /* Native methods are never recompiled. */
1348 return code->entrypoint;
1351 /* if there is no javacode, print error message and return empty method */
1353 if (m->jcode == NULL) {
1354 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
1356 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
1359 return code->entrypoint; /* return empty method */
1362 #if defined(ENABLE_STATISTICS)
1364 count_javacodesize += m->jcodelength + 18;
1365 count_tryblocks += jd->exceptiontablelength;
1366 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
1370 RT_TIMING_GET_TIME(time_checks);
1372 #if defined(WITH_CLASSPATH_SUN)
1373 /* Code for Sun's OpenJDK (see
1374 hotspot/src/share/vm/classfile/verifier.cpp
1375 (Verifier::is_eligible_for_verification)): Don't verify
1376 dynamically-generated bytecodes. */
1378 # if defined(ENABLE_VERIFIER)
1379 if (class_issubclass(m->class, class_sun_reflect_MagicAccessorImpl))
1380 jd->flags &= ~JITDATA_FLAG_VERIFY;
1384 /* call the compiler passes ***********************************************/
1386 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
1388 /* call parse pass */
1391 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
1395 RT_TIMING_GET_TIME(time_parse);
1397 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
1399 #if defined(ENABLE_JIT)
1400 # if defined(ENABLE_INTRP)
1403 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
1405 /* call stack analysis pass */
1407 if (!stack_analyse(jd)) {
1408 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
1412 RT_TIMING_GET_TIME(time_stack);
1414 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
1416 /* Build the CFG. This has to be done after stack_analyse, as
1417 there happens the JSR elimination. */
1422 #ifdef ENABLE_VERIFIER
1423 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1424 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
1426 /* call typecheck pass */
1427 if (!typecheck(jd)) {
1428 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
1433 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
1436 RT_TIMING_GET_TIME(time_typecheck);
1438 #if defined(ENABLE_LOOP)
1443 jit_renumber_basicblocks(jd);
1446 RT_TIMING_GET_TIME(time_loop);
1448 #if defined(ENABLE_IFCONV)
1449 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
1450 if (!ifconv_static(jd))
1452 jit_renumber_basicblocks(jd);
1455 RT_TIMING_GET_TIME(time_ifconv);
1459 #if defined(ENABLE_INLINING)
1460 if (JITDATA_HAS_FLAG_INLINE(jd)) {
1461 if (!inline_inline(jd))
1466 #if defined(ENABLE_PYTHON)
1467 if (!pythonpass_run(jd, "langauer_tarjan", "langauer_tarjan")) {
1472 #if defined(ENABLE_PROFILING)
1473 /* Basic block reordering. I think this should be done after
1474 if-conversion, as we could lose the ability to do the
1477 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1480 jit_renumber_basicblocks(jd);
1484 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
1486 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
1487 /* allocate registers */
1492 STATISTICS(count_methods_allocated_by_lsra++);
1495 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
1496 #if defined(ENABLE_SSA)
1497 /* allocate registers */
1498 if ((opt_lsra) && (jd->exceptiontablelength == 0)) {
1499 jd->ls = DNEW(lsradata);
1502 STATISTICS(count_methods_allocated_by_lsra++);
1505 # endif /* defined(ENABLE_SSA) */
1507 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
1512 STATISTICS(simplereg_make_statistics(jd));
1514 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
1515 # if defined(ENABLE_INTRP)
1518 #endif /* defined(ENABLE_JIT) */
1519 RT_TIMING_GET_TIME(time_alloc);
1521 #if defined(ENABLE_PROFILING)
1522 /* Allocate memory for basic block profiling information. This
1523 _must_ be done after loop optimization and register allocation,
1524 since they can change the basic block count. */
1526 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
1527 code->bbfrequency = MNEW(u4, jd->basicblockcount);
1530 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
1532 /* now generate the machine code */
1534 #if defined(ENABLE_JIT)
1535 # if defined(ENABLE_INTRP)
1537 #if defined(ENABLE_VERIFIER)
1539 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
1541 if (!typecheck_stackbased(jd)) {
1542 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
1547 if (!intrp_codegen(jd)) {
1548 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
1555 if (!codegen_generate(jd)) {
1556 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
1562 if (!intrp_codegen(jd)) {
1563 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
1568 RT_TIMING_GET_TIME(time_codegen);
1570 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
1572 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
1573 /* activate replacement points inside newly created code */
1575 if (opt_TestReplacement)
1576 replace_activate_replacement_points(code, false);
1579 #if !defined(NDEBUG)
1580 #if defined(ENABLE_DEBUG_FILTER)
1581 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
1584 /* intermediate and assembly code listings */
1586 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
1587 show_method(jd, SHOW_CODE);
1589 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
1590 # if defined(ENABLE_DISASSEMBLER)
1591 DISASSEMBLE(code->entrypoint,
1592 code->entrypoint + (code->mcodelength - cd->dseglen));
1596 if (opt_showddatasegment)
1601 /* switch to the newly generated code */
1604 assert(code->entrypoint);
1606 /* add the current compile version to the methodinfo */
1608 code->prev = m->code;
1611 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
1612 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
1613 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
1614 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
1615 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
1616 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
1617 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
1618 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
1620 /* return pointer to the methods entry point */
1622 return code->entrypoint;
1626 /* jit_invalidate_code *********************************************************
1628 Mark the compiled code of the given method as invalid and take care that
1629 it is replaced if necessary.
1631 XXX Not fully implemented, yet.
1633 *******************************************************************************/
1635 void jit_invalidate_code(methodinfo *m)
1641 if (code == NULL || code_is_invalid(code))
1644 code_flag_invalid(code);
1646 /* activate mappable replacement points */
1648 #if defined(ENABLE_REPLACEMENT)
1649 replace_activate_replacement_points(code, true);
1651 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
1656 /* jit_request_optimization ****************************************************
1658 Request optimization of the given method. If the code of the method is
1659 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
1660 triggers an optimized recompilation.
1661 If the method is already optimized, this function does nothing.
1664 m................the method
1666 *******************************************************************************/
1668 void jit_request_optimization(methodinfo *m)
1674 if (code && code->optlevel == 0)
1675 jit_invalidate_code(m);
1679 /* jit_get_current_code ********************************************************
1681 Get the currently valid code for the given method. If there is no valid
1682 code, (re)compile the method.
1685 m................the method
1688 the codeinfo* for the current code, or
1689 NULL if an exception has been thrown during recompilation.
1691 *******************************************************************************/
1693 codeinfo *jit_get_current_code(methodinfo *m)
1697 /* if we have valid code, return it */
1699 if (m->code && !code_is_invalid(m->code))
1702 /* otherwise: recompile */
1704 if (!jit_recompile(m))
1713 /* jit_asm_compile *************************************************************
1715 This method is called from asm_vm_call_method and does:
1717 - create stackframe info for exceptions
1718 - compile the method
1719 - patch the entrypoint of the method into the calculated address in
1721 - flushes the instruction cache.
1723 *******************************************************************************/
1725 #if defined(ENABLE_JIT)
1726 #if !defined(JIT_COMPILER_VIA_SIGNAL)
1727 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
1729 stackframeinfo_t sfi;
1734 /* create the stackframeinfo (subtract 1 from RA as it points to the */
1735 /* instruction after the call) */
1737 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
1739 /* actually compile the method */
1741 entrypoint = jit_compile(m);
1743 /* remove the stackframeinfo */
1745 stacktrace_stackframeinfo_remove(&sfi);
1747 /* there was a problem during compilation */
1749 if (entrypoint == NULL)
1752 /* get the method patch address */
1754 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1756 /* patch the method entry point */
1760 *p = (ptrint) entrypoint;
1762 /* flush the instruction cache */
1764 md_icacheflush(pa, SIZEOF_VOID_P);
1770 /* jit_compile_handle **********************************************************
1772 This method is called from the appropriate signal handler which
1773 handles compiler-traps and does the following:
1775 - compile the method
1776 - patch the entrypoint of the method into the calculated address in
1778 - flush the instruction cache
1780 *******************************************************************************/
1782 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1784 void *newpv; /* new compiled method PV */
1785 void *pa; /* patch address */
1786 uintptr_t *p; /* convenience pointer */
1788 /* Compile the method. */
1790 newpv = jit_compile(m);
1792 /* There was a problem during compilation. */
1797 /* Get the method patch address. */
1799 pa = md_jit_method_patch_address(pv, ra, mptr);
1801 /* Patch the method entry point. */
1803 p = (uintptr_t *) pa;
1805 *p = (uintptr_t) newpv;
1807 /* Flush both caches. */
1809 md_cacheflush(pa, SIZEOF_VOID_P);
1813 #endif /* defined(ENABLE_JIT) */
1816 /* jit_complement_condition ****************************************************
1818 Returns the complement of the passed conditional instruction.
1820 We use the order of the different conditions, e.g.:
1825 If the passed opcode is odd, we simply add 1 to get the complement.
1826 If the opcode is even, we subtract 1.
1833 *******************************************************************************/
1835 s4 jit_complement_condition(s4 opcode)
1839 return ICMD_IFNONNULL;
1841 case ICMD_IFNONNULL:
1845 /* check if opcode is odd */
1855 /* jit_renumber_basicblocks ****************************************************
1857 Set the ->nr of all blocks so it increases when traversing ->next.
1860 jitdata..........the current jitdata
1862 *******************************************************************************/
1864 void jit_renumber_basicblocks(jitdata *jd)
1870 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1874 /* we have one block more than jd->basicblockcount (the end marker) */
1876 assert(nr == jd->basicblockcount + 1);
1880 /* jit_check_basicblock_numbers ************************************************
1882 Assert that the ->nr of the first block is zero and increases by 1 each
1883 time ->next is traversed.
1884 This function should be called before any analysis that relies on
1885 the basicblock numbers.
1888 jitdata..........the current jitdata
1890 NOTE: Aborts with an assertion if the condition is not met!
1892 *******************************************************************************/
1894 #if !defined(NDEBUG)
1895 void jit_check_basicblock_numbers(jitdata *jd)
1901 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1902 assert(bptr->nr == nr);
1906 /* we have one block more than jd->basicblockcount (the end marker) */
1908 assert(nr == jd->basicblockcount + 1);
1910 #endif /* !defined(NDEBUG) */
1914 * These are local overrides for various environment variables in Emacs.
1915 * Please do not remove this and leave it at the end of the file, where
1916 * Emacs will automagically detect them.
1917 * ---------------------------------------------------------------------
1920 * indent-tabs-mode: t
1924 * vim:noexpandtab:sw=4:ts=4: