Line data Source code
1 : /* src/vm/jit/stack.cpp - stack analysis
2 :
3 : Copyright (C) 1996-2014
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 : #include "vm/jit/stack.hpp"
26 :
27 : #include "config.h" // for ENABLE_VERIFIER, etc
28 :
29 : #include <stdint.h> // for int32_t
30 : #include <cassert> // for assert
31 : #include <climits>
32 : #include <cstdio> // for NULL
33 : #include <cstring>
34 :
35 : #include "arch.hpp"
36 : #include "md-abi.hpp"
37 :
38 : #include "native/native.hpp"
39 :
40 : #include "mm/dumpmemory.hpp"
41 :
42 : #include "toolbox/logging.hpp"
43 :
44 : #include "vm/descriptor.hpp" // for methoddesc, typedesc, etc
45 : #include "vm/exceptions.hpp"
46 : #include "vm/global.hpp" // for Type::TYPE_INT, etc
47 : #include "vm/options.hpp" // for opt_verify
48 : #include "vm/references.hpp" // for classref_or_classinfo, etc
49 : #include "vm/resolve.hpp" // for unresolved_field
50 : #include "vm/statistics.hpp" // for StatVar, StatDist, etc
51 : #include "vm/types.hpp" // for s4, ptrint
52 :
53 : #include "vm/jit/abi.hpp" // for md_return_alloc
54 : #include "vm/jit/builtin.hpp" // for builtintable_get_internal, etc
55 : #include "vm/jit/cfg.hpp"
56 : #include "vm/jit/code.hpp" // for code_unflag_leafmethod
57 : #include "vm/jit/codegen-common.hpp"
58 : #include "vm/jit/jit.hpp" // for basicblock, jitdata, etc
59 : #include "vm/jit/parse.hpp"
60 : #include "vm/jit/reg.hpp" // for varinfo, etc
61 : #include "vm/jit/show.hpp"
62 : #include "vm/jit/verify/typeinfo.hpp" // for typeinfo_t
63 :
64 : #include "vm/jit/ir/icmd.hpp" // for ::ICMD_ACONST
65 : #include "vm/jit/ir/instruction.hpp" // for instruction, etc
66 :
67 : #if defined(ENABLE_DISASSEMBLER)
68 : # include "vm/jit/disass.hpp"
69 : #endif
70 :
71 : #if 0
72 : #if defined(ENABLE_SSA)
73 : # include "vm/jit/optimizing/lsra.hpp"
74 : # include "vm/jit/optimizing/ssa.hpp"
75 : #elif defined(ENABLE_LSRA)
76 : # include "vm/jit/allocator/lsra.hpp"
77 : #endif
78 : #endif
79 :
80 : using namespace cacao;
81 :
82 :
83 : //#define STACK_VERBOSE
84 :
85 :
86 : /* For returnAddresses we use a field of the typeinfo to store from which */
87 : /* subroutine the returnAddress will return, if used. */
88 : /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
89 : /* to need it initialised to NULL. This should be investigated. */
90 :
91 : #if defined(ENABLE_VERIFIER)
92 : #define SBRSTART typeinfo.elementclass.any
93 : #endif
94 :
95 : STAT_REGISTER_VAR(int,count_basic_blocks,0,"basic blocks","Number of compiled basic blocks")
96 : STAT_REGISTER_VAR(int,count_max_basic_blocks,0,"max basic blocks","Number of max. basic blocks per method")
97 : STAT_REGISTER_VAR(int,count_javainstr,0,"java inst","Number of compiled JavaVM instructions")
98 : STAT_REGISTER_VAR(int,count_max_javainstr,0,"max java inst","Number of max. JavaVM instructions per method")
99 :
100 :
101 : //STAT_REGISTER_VAR(int,count_pcmd_activ,0,"count_pcmd_activ","Number of Activ Pseudocommands")
102 : //STAT_REGISTER_VAR(int,count_pcmd_drop,0,"count_pcmd_drop","Number of Drop Pseudocommands")
103 : //STAT_REGISTER_VAR(int,count_pcmd_move,0,"count_pcmd_move","Number of Move Pseudocommands")
104 : STAT_REGISTER_VAR(int,count_load_instruction,0,"load instruction","Number of Load Pseudocommands")
105 : STAT_REGISTER_VAR(int,count_pcmd_op,0,"pcmd op","Number of OP Pseudocommands")
106 : STAT_REGISTER_VAR(int,count_dup_instruction,0,"dup instruction","Number of DUP Pseudocommands")
107 : STAT_REGISTER_VAR(int,count_pcmd_mem,0,"pcmd mem","Number of Mem Pseudocommands")
108 : STAT_REGISTER_VAR(int,count_pcmd_met,0,"pcmd met","Number of Method Pseudocommands")
109 : STAT_REGISTER_VAR(int,count_pcmd_table,0,"pcmd table","Number of Table Pseudocommands")
110 : STAT_REGISTER_VAR(int,count_check_null,0,"check null","Number of Null Pointer Checks")
111 : STAT_REGISTER_VAR(int,count_check_bound,0,"check bound","Number of Array Bound Checks")
112 : STAT_REGISTER_VAR(int,count_max_new_stack,0,"max new stack","Maximal count of stack elements")
113 : STAT_REGISTER_VAR(int,count_upper_bound_new_stack,0,"upper bound new stack","Upper bound of max stack elements")
114 :
115 : STAT_REGISTER_GROUP(const_pcmd_stat,"const pcmd","Number of Const Pseudocommands")
116 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_load,0,"pcmd load","Number of Const Pseudocommands (load)",const_pcmd_stat)
117 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_zero,0,"pcmd zero","Number of Const Pseudocommands (zero)",const_pcmd_stat)
118 :
119 : #if 0
120 : // not used
121 : STAT_REGISTER_GROUP(constalu_pcmd_stat,"const alu pcmd","Number of ConstAlu Pseudocommands")
122 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_const_alu,0,"count_pcmd_const_alu","Number of ConstAlu Pseudocommands",constalu_pcmd_stat)
123 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_const_bra,0,"count_pcmd_const_bra","Number of ConstAlu Pseudocommands (cmp)",constalu_pcmd_stat)
124 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_const_store,0,"count_pcmd_const_store","Number of ConstAlu Pseudocommands (store)",constalu_pcmd_stat)
125 : #endif
126 :
127 : STAT_REGISTER_VAR(int,count_pcmd_store,0,"count_pcmd_store","Number of Store Pseudocommands")
128 : // count_pcmd_store_comb?
129 :
130 : STAT_REGISTER_GROUP(branch_pcmd_stat,"branch pcmd","Number of Branch Pseudocommands")
131 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_bra,0,"count_pcmd_bra","Number of Branch Pseudocommands",branch_pcmd_stat)
132 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_return,0,"count_pcmd_return","Number of Branch Pseudocommands (rets)",branch_pcmd_stat)
133 : STAT_REGISTER_GROUP_VAR(int,count_pcmd_returnx,0,"count_pcmd_returnx","Number of Branch Pseudocommands (Xrets)",branch_pcmd_stat)
134 :
135 : STAT_REGISTER_DIST(unsigned int,unsigned int,count_block_stack,0,9,1,0,"stack size dist","Distribution of stack sizes at block boundary")
136 : STAT_REGISTER_DIST(unsigned int,unsigned int,count_store_depth,0,9,1,0,"store stack depth dist","Distribution of store stack depth")
137 : STAT_REGISTER_DIST(unsigned int,unsigned int,count_store_length,0,19,1,0,"store creator chains","Distribution of store creator chains")
138 : STAT_REGISTER_DIST(unsigned int,unsigned int,count_analyse_iterations,1,4,1,0,"analysis iter.","Distribution of analysis iterations")
139 :
140 : #if defined(ENABLE_STATISTICS)
141 : static const unsigned int count_method_bb_distribution_range[] = {5,10,15,20,30,40,50,75};
142 : static const unsigned int count_block_size_distribution_range[] = {0,1,2,3,4,5,6,7,8,9,12,14,16,18,20,25,30};
143 : #endif
144 :
145 : STAT_REGISTER_DIST_RANGE(unsigned int,unsigned int,count_method_bb_distribution,count_method_bb_distribution_range,8,0,"method bb dist.","Distribution of basic blocks per method")
146 : STAT_REGISTER_DIST_RANGE(unsigned int,unsigned int,count_block_size_distribution,count_block_size_distribution_range,17,0,"bb size dist.","Distribution of basic block sizes")
147 :
148 :
149 : /* stackdata_t *****************************************************************
150 :
151 : This struct holds internal data during stack analysis.
152 :
153 : *******************************************************************************/
154 :
155 : struct stackdata_t {
156 : bool analyse(jitdata*);
157 :
158 : basicblock *bptr; /* the current basic block being analysed */
159 : stackelement_t *new_elem; /* next free stackelement */
160 : s4 vartop; /* next free variable index */
161 : s4 localcount; /* number of locals (at the start of var) */
162 : s4 varcount; /* maximum number of variables expected */
163 : s4 varsallocated; /* total number of variables allocated */
164 : s4 maxlocals; /* max. number of Java locals */
165 : varinfo *var; /* variable array (same as jd->var) */
166 : s4 *javalocals; /* map from Java locals to jd->var indices */
167 : methodinfo *m; /* the method being analysed */
168 : jitdata *jd; /* current jitdata */
169 : basicblock *last_real_block; /* the last block before the empty one */
170 : bool repeat; /* if true, iterate the analysis again */
171 : exception_entry **handlers; /* exception handlers for the current block */
172 : exception_entry *extableend; /* points to the last exception entry */
173 : stackelement_t exstack; /* instack for exception handlers */
174 : private:
175 0 : bool throw_stack_underflow() {
176 0 : exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
177 0 : return false;
178 : }
179 0 : bool throw_stack_overflow() {
180 0 : exceptions_throw_verifyerror(m, "Stack size too large");
181 0 : return false;
182 : }
183 7 : bool throw_stack_type_error(Type expectedtype) {
184 7 : exceptions_throw_verifyerror_for_stack(m, expectedtype);
185 7 : return false;
186 : }
187 0 : bool throw_stack_category_error() {
188 0 : exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
189 0 : return false;
190 : }
191 : };
192 :
193 :
194 : /* macros used internally by analyse_stack ************************************/
195 :
196 : /*--------------------------------------------------*/
197 : /* BASIC TYPE CHECKING */
198 : /*--------------------------------------------------*/
199 :
200 : /* XXX would be nice if we did not have to pass the expected type */
201 :
202 : #if defined(ENABLE_VERIFIER)
203 : # define CHECK_BASIC_TYPE(expected,actual) \
204 : do { \
205 : if ((actual) != (expected)) { \
206 : return throw_stack_type_error((Type) (expected)); \
207 : } \
208 : } while (0)
209 : #else
210 : # define CHECK_BASIC_TYPE(expected,actual)
211 : #endif
212 :
213 : /*--------------------------------------------------*/
214 : /* STACK UNDERFLOW/OVERFLOW CHECKS */
215 : /*--------------------------------------------------*/
216 :
217 : /* underflow checks */
218 :
219 : #if defined(ENABLE_VERIFIER)
220 : # define REQUIRE(num) \
221 : do { \
222 : if (stackdepth < (num)) \
223 : return throw_stack_underflow(); \
224 : } while (0)
225 : #else
226 : #define REQUIRE(num)
227 : #endif
228 :
229 :
230 : /* overflow check */
231 : /* We allow ACONST instructions inserted as arguments to builtin
232 : * functions to exceed the maximum stack depth. Maybe we should check
233 : * against maximum stack depth only at block boundaries?
234 : */
235 :
236 : /* XXX we should find a way to remove the opc/op1 check */
237 : #if defined(ENABLE_VERIFIER)
238 : # define CHECKOVERFLOW \
239 : do { \
240 : if (stackdepth > m->maxstack) \
241 : if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr)) \
242 : return throw_stack_overflow(); \
243 : } while(0)
244 : #else
245 : # define CHECKOVERFLOW
246 : #endif
247 :
248 :
249 : /* macros for allocating/releasing variable indices *****************/
250 :
251 : #define GET_NEW_INDEX(sd, new_varindex) \
252 : do { \
253 : assert((sd).vartop < (sd).varcount); \
254 : (new_varindex) = ((sd).vartop)++; \
255 : } while (0)
256 :
257 : /* Not implemented now - could be used to reuse varindices. */
258 : /* Pay attention to not release a localvar once implementing it! */
259 : #define RELEASE_INDEX(sd, varindex)
260 :
261 : #define GET_NEW_VAR(sd, newvarindex, newtype) \
262 : do { \
263 : GET_NEW_INDEX((sd), (newvarindex)); \
264 : (sd).var[newvarindex].type = (newtype); \
265 : } while (0)
266 :
267 :
268 : /* macros for querying variable properties **************************/
269 :
270 : #define IS_INOUT(sp) \
271 : (sd.var[(sp)->varnum].flags & INOUT)
272 :
273 : #define IS_PREALLOC(sp) \
274 : (sd.var[(sp)->varnum].flags & PREALLOC)
275 :
276 : #define IS_TEMPVAR(sp) \
277 : ( ((sp)->varnum >= sd.localcount) \
278 : && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
279 :
280 :
281 : #define IS_LOCALVAR_SD(sd, sp) \
282 : ((sp)->varnum < (sd).localcount)
283 :
284 : #define IS_LOCALVAR(sp) \
285 : IS_LOCALVAR_SD(sd, (sp))
286 :
287 :
288 : /* macros for setting variable properties ****************************/
289 :
290 : #define SET_TEMPVAR(sp) \
291 : do { \
292 : if (IS_LOCALVAR((sp))) { \
293 : stack_change_to_tempvar(&sd, (sp), iptr); \
294 : } \
295 : sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
296 : } while (0);
297 :
298 : #define SET_PREALLOC(sp) \
299 : do { \
300 : assert(!IS_LOCALVAR((sp))); \
301 : sd.var[(sp)->varnum].flags |= PREALLOC; \
302 : } while (0);
303 :
304 :
305 : /* macros for source operands ***************************************/
306 :
307 : #define CLR_S1 \
308 : (iptr->s1.varindex = -1)
309 :
310 : #define USE_S1(type1) \
311 : do { \
312 : REQUIRE(1); \
313 : CHECK_BASIC_TYPE(type1, curstack->type); \
314 : iptr->s1.varindex = curstack->varnum; \
315 : } while (0)
316 :
317 : #define USE_S1_ANY \
318 : do { \
319 : REQUIRE(1); \
320 : iptr->s1.varindex = curstack->varnum; \
321 : } while (0)
322 :
323 : #define USE_S1_S2(type1, type2) \
324 : do { \
325 : REQUIRE(2); \
326 : CHECK_BASIC_TYPE(type1, curstack->prev->type); \
327 : CHECK_BASIC_TYPE(type2, curstack->type); \
328 : iptr->sx.s23.s2.varindex = curstack->varnum; \
329 : iptr->s1.varindex = curstack->prev->varnum; \
330 : } while (0)
331 :
332 : #define USE_S1_S2_ANY_ANY \
333 : do { \
334 : REQUIRE(2); \
335 : iptr->sx.s23.s2.varindex = curstack->varnum; \
336 : iptr->s1.varindex = curstack->prev->varnum; \
337 : } while (0)
338 :
339 : #define USE_S1_S2_S3(type1, type2, type3) \
340 : do { \
341 : REQUIRE(3); \
342 : CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
343 : CHECK_BASIC_TYPE(type2, curstack->prev->type); \
344 : CHECK_BASIC_TYPE(type3, curstack->type); \
345 : iptr->sx.s23.s3.varindex = curstack->varnum; \
346 : iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
347 : iptr->s1.varindex = curstack->prev->prev->varnum; \
348 : } while (0)
349 :
350 : /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
351 : #define POPANY \
352 : do { \
353 : if (curstack->varkind == UNDEFVAR) \
354 : curstack->varkind = TEMPVAR; \
355 : curstack = curstack->prev; \
356 : } while (0)
357 :
358 : #define POP_S1(type1) \
359 : do { \
360 : USE_S1(type1); \
361 : if (curstack->varkind == UNDEFVAR) \
362 : curstack->varkind = TEMPVAR; \
363 : curstack = curstack->prev; \
364 : } while (0)
365 :
366 : #define POP_S1_ANY \
367 : do { \
368 : USE_S1_ANY; \
369 : if (curstack->varkind == UNDEFVAR) \
370 : curstack->varkind = TEMPVAR; \
371 : curstack = curstack->prev; \
372 : } while (0)
373 :
374 : #define POP_S1_S2(type1, type2) \
375 : do { \
376 : USE_S1_S2(type1, type2); \
377 : if (curstack->varkind == UNDEFVAR) \
378 : curstack->varkind = TEMPVAR; \
379 : if (curstack->prev->varkind == UNDEFVAR) \
380 : curstack->prev->varkind = TEMPVAR; \
381 : curstack = curstack->prev->prev; \
382 : } while (0)
383 :
384 : #define POP_S1_S2_ANY_ANY \
385 : do { \
386 : USE_S1_S2_ANY_ANY; \
387 : if (curstack->varkind == UNDEFVAR) \
388 : curstack->varkind = TEMPVAR; \
389 : if (curstack->prev->varkind == UNDEFVAR) \
390 : curstack->prev->varkind = TEMPVAR; \
391 : curstack = curstack->prev->prev; \
392 : } while (0)
393 :
394 : #define POP_S1_S2_S3(type1, type2, type3) \
395 : do { \
396 : USE_S1_S2_S3(type1, type2, type3); \
397 : if (curstack->varkind == UNDEFVAR) \
398 : curstack->varkind = TEMPVAR; \
399 : if (curstack->prev->varkind == UNDEFVAR) \
400 : curstack->prev->varkind = TEMPVAR; \
401 : if (curstack->prev->prev->varkind == UNDEFVAR) \
402 : curstack->prev->prev->varkind = TEMPVAR; \
403 : curstack = curstack->prev->prev->prev; \
404 : } while (0)
405 :
406 : #define CLR_SX \
407 : (iptr->sx.val.l = 0)
408 :
409 :
410 : /* macros for setting the destination operand ***********************/
411 :
412 : #define CLR_DST \
413 : (iptr->dst.varindex = -1)
414 :
415 : #define DST(typed, index) \
416 : do { \
417 : NEWSTACKn((typed),(index)); \
418 : curstack->creator = iptr; \
419 : iptr->dst.varindex = (index); \
420 : } while (0)
421 :
422 : #define DST_LOCALVAR(typed, index) \
423 : do { \
424 : NEWSTACK((typed), LOCALVAR, (index)); \
425 : curstack->creator = iptr; \
426 : iptr->dst.varindex = (index); \
427 : } while (0)
428 :
429 :
430 : /* macro for propagating constant values ****************************/
431 :
432 : #if defined(ENABLE_VERIFIER)
433 : #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
434 : do { \
435 : if (((dv)->type = (sv)->type) == TYPE_RET) { \
436 : (dv)->vv = (sv)->vv; \
437 : (dv)->SBRSTART = (sv)->SBRSTART; \
438 : } \
439 : } while (0)
440 : #else
441 : #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
442 : do { \
443 : (dv)->type = (sv)->type; \
444 : if (((dv)->type = (sv)->type) == TYPE_RET) { \
445 : (dv)->vv = (sv)->vv; \
446 : } \
447 : } while (0)
448 : #endif
449 :
450 : #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
451 : COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
452 :
453 :
454 : /* stack modelling macros *******************************************/
455 :
456 : #define OP0_1(typed) \
457 : do { \
458 : CLR_S1; \
459 : GET_NEW_VAR(sd, new_index, (typed)); \
460 : DST((typed), new_index); \
461 : stackdepth++; \
462 : } while (0)
463 :
464 : #define OP1_0_ANY \
465 : do { \
466 : POP_S1_ANY; \
467 : CLR_DST; \
468 : stackdepth--; \
469 : } while (0)
470 :
471 : #define OP1_BRANCH(type1) \
472 : do { \
473 : POP_S1(type1); \
474 : stackdepth--; \
475 : } while (0)
476 :
477 : #define OP1_1(type1, typed) \
478 : do { \
479 : POP_S1(type1); \
480 : GET_NEW_VAR(sd, new_index, (typed)); \
481 : DST(typed, new_index); \
482 : } while (0)
483 :
484 : #define OP2_1(type1, type2, typed) \
485 : do { \
486 : POP_S1_S2(type1, type2); \
487 : GET_NEW_VAR(sd, new_index, ((Type) (typed))); \
488 : DST(((Type) (typed)), new_index); \
489 : stackdepth--; \
490 : } while (0)
491 :
492 : #define OP0_0 \
493 : do { \
494 : CLR_S1; \
495 : CLR_DST; \
496 : } while (0)
497 :
498 : #define OP0_BRANCH \
499 : do { \
500 : CLR_S1; \
501 : } while (0)
502 :
503 : #define OP1_0(type1) \
504 : do { \
505 : POP_S1(type1); \
506 : CLR_DST; \
507 : stackdepth--; \
508 : } while (0)
509 :
510 : #define OP2_0(type1, type2) \
511 : do { \
512 : POP_S1_S2(type1, type2); \
513 : CLR_DST; \
514 : stackdepth -= 2; \
515 : } while (0)
516 :
517 : #define OP2_BRANCH(type1, type2) \
518 : do { \
519 : POP_S1_S2(type1, type2); \
520 : stackdepth -= 2; \
521 : } while (0)
522 :
523 : #define OP2_0_ANY_ANY \
524 : do { \
525 : POP_S1_S2_ANY_ANY; \
526 : CLR_DST; \
527 : stackdepth -= 2; \
528 : } while (0)
529 :
530 : #define OP3_0(type1, type2, type3) \
531 : do { \
532 : POP_S1_S2_S3(type1, type2, type3); \
533 : CLR_DST; \
534 : stackdepth -= 3; \
535 : } while (0)
536 :
537 : #define LOAD(type1, index) \
538 : do { \
539 : DST_LOCALVAR(type1, index); \
540 : stackdepth++; \
541 : } while (0)
542 :
543 : #define STORE(type1, index) \
544 : do { \
545 : POP_S1(type1); \
546 : stackdepth--; \
547 : } while (0)
548 :
549 :
550 : /* macros for DUP elimination ***************************************/
551 :
552 : /* XXX replace NEW_VAR with NEW_INDEX */
553 : #define DUP_SLOT(sp) \
554 : do { \
555 : GET_NEW_VAR(sd, new_index, (sp)->type); \
556 : COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
557 : NEWSTACK((sp)->type, TEMPVAR, new_index); \
558 : } while(0)
559 :
560 : /* does not check input stackdepth */
561 : #define MOVE_UP(sp) \
562 : do { \
563 : iptr->opc = ICMD_MOVE; \
564 : iptr->s1.varindex = (sp)->varnum; \
565 : DUP_SLOT(sp); \
566 : curstack->creator = iptr; \
567 : iptr->dst.varindex = curstack->varnum; \
568 : stackdepth++; \
569 : } while (0)
570 :
571 : /* does not check input stackdepth */
572 : #define COPY_UP(sp) \
573 : do { \
574 : SET_TEMPVAR((sp)); \
575 : iptr->opc = ICMD_COPY; \
576 : iptr->s1.varindex = (sp)->varnum; \
577 : DUP_SLOT(sp); \
578 : curstack->creator = iptr; \
579 : iptr->dst.varindex = curstack->varnum; \
580 : stackdepth++; \
581 : } while (0)
582 :
583 : #define COPY_DOWN(s, d) \
584 : do { \
585 : SET_TEMPVAR((s)); \
586 : iptr->opc = ICMD_COPY; \
587 : iptr->s1.varindex = (s)->varnum; \
588 : iptr->dst.varindex = (d)->varnum; \
589 : (d)->creator = iptr; \
590 : } while (0)
591 :
592 : #define MOVE_TO_TEMP(sp) \
593 : do { \
594 : GET_NEW_INDEX(sd, new_index); \
595 : iptr->opc = ICMD_MOVE; \
596 : iptr->s1.varindex = (sp)->varnum; \
597 : iptr->dst.varindex = new_index; \
598 : COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
599 : (sp)->varnum = new_index; \
600 : (sp)->varkind = TEMPVAR; \
601 : } while (0)
602 :
603 : /* macros for branching / reaching basic blocks *********************/
604 :
605 : #define BRANCH_TARGET(bt, tempbptr) \
606 : do { \
607 : tempbptr = (bt).block; \
608 : tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
609 : stackdepth); \
610 : if (tempbptr == NULL) \
611 : return false; \
612 : (bt).block = tempbptr; \
613 : } while (0)
614 :
615 : #define BRANCH(tempbptr) \
616 : BRANCH_TARGET(iptr->dst, tempbptr)
617 :
618 :
619 : /*--------------------------------------------------*/
620 : /* ALLOCATING STACK SLOTS */
621 : /*--------------------------------------------------*/
622 :
623 : #define NEWSTACK(s,v,n) \
624 : do { \
625 : sd.new_elem->prev = curstack; \
626 : sd.new_elem->type = (s); \
627 : sd.new_elem->flags = 0; \
628 : sd.new_elem->varkind = (v); \
629 : sd.new_elem->varnum = (n); \
630 : curstack = sd.new_elem; \
631 : sd.var[(n)].type = (s); \
632 : sd.var[(n)].flags = 0; \
633 : sd.new_elem++; \
634 : } while (0)
635 :
636 : /* Initialize regoff, so -sia can show regnames even before reg.inc */
637 : /* regs[rd->intregargnum] has to be set for this */
638 : /* new_elem->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; } */
639 :
640 : #define NEWSTACKn(s,n) NEWSTACK(s,UNDEFVAR,n)
641 : #define NEWSTACK0(s) NEWSTACK(s,UNDEFVAR,0)
642 :
643 : /* forward declarations *******************************************************/
644 :
645 : static void stack_create_invars(stackdata_t *sd, basicblock *b,
646 : stackelement_t * curstack, int stackdepth);
647 : static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
648 :
649 : #if defined(STACK_VERBOSE)
650 : static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
651 : static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
652 : static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
653 : static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
654 : static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
655 : static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
656 : stackelement_t * curstack);
657 : #endif
658 :
659 :
660 : /* stack_init ******************************************************************
661 :
662 : Initialized the stack analysis subsystem (called by jit_init).
663 :
664 : *******************************************************************************/
665 :
666 163 : bool stack_init(void)
667 : {
668 163 : return true;
669 : }
670 :
671 :
672 : /* stack_grow_variable_array ***************************************************
673 :
674 : Grow the variable array so the given number of additional variables fits in.
675 : The number is added to `varcount`, which is the maximum number of variables
676 : we expect to need at this point. The actual number of variables
677 : (`varsallocated`) may be larger than that, in order to avoid too many
678 : reallocations.
679 :
680 : IN:
681 : sd...........stack analysis data
682 : num..........number of additional variables
683 :
684 : *******************************************************************************/
685 :
686 22 : static void stack_grow_variable_array(stackdata_t *sd, s4 num)
687 : {
688 : s4 newsize;
689 :
690 22 : assert(num >= 0);
691 :
692 22 : if (sd->varcount + num > sd->varsallocated) {
693 4 : newsize = 2*sd->varsallocated + num;
694 :
695 4 : sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
696 4 : MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
697 4 : sd->varsallocated = newsize;
698 4 : sd->jd->var = sd->var;
699 : }
700 :
701 22 : sd->varcount += num;
702 22 : sd->jd->varcount += num;
703 :
704 22 : assert(sd->varcount <= sd->varsallocated);
705 22 : }
706 :
707 :
708 : /* stack_append_block **********************************************************
709 :
710 : Append the given block after the last real block of the method (before
711 : the pseudo-block at the end).
712 :
713 : IN:
714 : sd...........stack analysis data
715 : b............the block to append
716 :
717 : *******************************************************************************/
718 :
719 11 : static void stack_append_block(stackdata_t *sd, basicblock *b)
720 : {
721 : #if defined(STACK_VERBOSE)
722 : printf("APPENDING BLOCK L%0d\n", b->nr);
723 : #endif
724 :
725 11 : b->next = sd->last_real_block->next;
726 11 : sd->last_real_block->next = b;
727 11 : sd->last_real_block = b;
728 11 : b->nr = sd->jd->basicblockcount++;
729 11 : b->next->nr = b->nr + 1;
730 11 : }
731 :
732 :
733 : /* stack_clone_block ***********************************************************
734 :
735 : Create a copy of the given block and insert it at the end of the method.
736 :
737 : CAUTION: This function does not copy the any variables or the instruction
738 : list. It _does_, however, reserve space for the block's invars in the
739 : variable array.
740 :
741 : IN:
742 : sd...........stack analysis data
743 : b............the block to clone
744 :
745 : RETURN VALUE:
746 : a pointer to the copy
747 :
748 : *******************************************************************************/
749 :
750 11 : static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
751 : {
752 : basicblock *clone;
753 :
754 11 : clone = DNEW(basicblock);
755 11 : *clone = *b;
756 :
757 11 : clone->iinstr = NULL;
758 11 : clone->inlocals = NULL;
759 11 : clone->javalocals = NULL;
760 11 : clone->invars = NULL;
761 :
762 11 : clone->original = (b->original) ? b->original : b;
763 11 : clone->copied_to = clone->original->copied_to;
764 11 : clone->original->copied_to = clone;
765 11 : clone->next = NULL;
766 11 : clone->state = basicblock::REACHED;
767 :
768 11 : stack_append_block(sd, clone);
769 :
770 : /* reserve space for the invars of the clone */
771 :
772 11 : stack_grow_variable_array(sd, b->indepth);
773 :
774 : #if defined(STACK_VERBOSE)
775 : printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
776 : #endif
777 :
778 11 : return clone;
779 : }
780 :
781 :
782 : /* stack_create_locals *********************************************************
783 :
784 : Create the local variables for the start of the given basic block.
785 :
786 : IN:
787 : sd...........stack analysis data
788 : b............block to create the locals for
789 :
790 : *******************************************************************************/
791 :
792 232945 : static void stack_create_locals(stackdata_t *sd, basicblock *b)
793 : {
794 : s4 i;
795 : s4 *jl;
796 : varinfo *dv;
797 :
798 : /* copy the current state of the local variables */
799 : /* (one extra local is needed by the verifier) */
800 :
801 232945 : dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
802 232945 : b->inlocals = dv;
803 1574622 : for (i=0; i<sd->localcount; ++i)
804 1341677 : *dv++ = sd->var[i];
805 :
806 : /* the current map from java locals to cacao variables */
807 :
808 232945 : jl = DMNEW(s4, sd->maxlocals);
809 232945 : b->javalocals = jl;
810 232945 : MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
811 232945 : }
812 :
813 :
814 : /* stack_merge_locals **********************************************************
815 :
816 : Merge local variables at the beginning of the given basic block.
817 :
818 : IN:
819 : sd...........stack analysis data
820 : b............the block that is reached
821 :
822 : *******************************************************************************/
823 :
824 103429 : static void stack_merge_locals(stackdata_t *sd, basicblock *b)
825 : {
826 : s4 i;
827 : #if defined(ENABLE_VERIFIER)
828 : varinfo *dv;
829 : varinfo *sv;
830 : #endif
831 :
832 : /* If a javalocal is mapped to different cacao locals along the */
833 : /* incoming control-flow edges, it becomes undefined. */
834 :
835 790205 : for (i=0; i<sd->maxlocals; ++i) {
836 686776 : if (b->javalocals[i] != jitdata::UNUSED && b->javalocals[i] != sd->javalocals[i]) {
837 2902 : b->javalocals[i] = jitdata::UNUSED;
838 2902 : if (b->state >= basicblock::FINISHED)
839 32 : b->state = basicblock::TYPECHECK_REACHED;
840 2902 : if (b->nr <= sd->bptr->nr)
841 10 : sd->repeat = true;
842 : }
843 : }
844 :
845 : #if defined(ENABLE_VERIFIER)
846 103429 : if (b->inlocals) {
847 837043 : for (i=0; i<sd->localcount; ++i) {
848 733614 : dv = b->inlocals + i;
849 733614 : sv = sd->var + i;
850 733614 : if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
851 : && (sv->SBRSTART != dv->SBRSTART))
852 : {
853 : #if defined(STACK_VERBOSE)
854 : printf("JSR MISMATCH: setting variable %d to VOID\n", i);
855 : #endif
856 2 : dv->type = TYPE_VOID;
857 2 : if (b->state >= basicblock::FINISHED)
858 1 : b->state = basicblock::TYPECHECK_REACHED;
859 2 : sd->repeat = true; /* This is very rare, so just repeat */
860 : }
861 : }
862 : }
863 : #endif /* defined(ENABLE_VERIFIER) */
864 103429 : }
865 :
866 :
867 : /* stack_create_invars *********************************************************
868 :
869 : Create the invars for the given basic block. Also make a copy of the locals.
870 :
871 : IN:
872 : sd...........stack analysis data
873 : b............block to create the invars for
874 : curstack.....current stack top
875 : stackdepth...current stack depth
876 :
877 : This function creates STACKDEPTH invars and sets their types to the
878 : types to the types of the corresponding slot in the current stack.
879 :
880 : *******************************************************************************/
881 :
882 120018 : static void stack_create_invars(stackdata_t *sd, basicblock *b,
883 : stackelement_t * curstack, int stackdepth)
884 : {
885 : stackelement_t * sp;
886 : int i;
887 : int index;
888 : varinfo *dv;
889 : varinfo *sv;
890 :
891 120018 : assert(sd->vartop + stackdepth <= sd->varcount);
892 :
893 120018 : b->indepth = stackdepth;
894 120018 : b->invars = DMNEW(s4, stackdepth);
895 :
896 : /* allocate the variable indices */
897 120018 : index = (sd->vartop += stackdepth);
898 :
899 120018 : i = stackdepth;
900 142842 : for (sp = curstack; i--; sp = sp->prev) {
901 22824 : b->invars[i] = --index;
902 22824 : dv = sd->var + index;
903 22824 : sv = sd->var + sp->varnum;
904 22824 : dv->flags = INOUT;
905 22824 : COPY_VAL_AND_TYPE_VAR(sv, dv);
906 : }
907 :
908 120018 : stack_create_locals(sd, b);
909 120018 : }
910 :
911 :
912 : /* stack_create_invars_from_outvars ********************************************
913 :
914 : Create the invars for the given basic block. Also make a copy of the locals.
915 : Types are propagated from the outvars of the current block.
916 :
917 : IN:
918 : sd...........stack analysis data
919 : b............block to create the invars for
920 :
921 : *******************************************************************************/
922 :
923 112927 : static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
924 : {
925 : int i;
926 : int n;
927 : varinfo *sv, *dv;
928 :
929 112927 : n = sd->bptr->outdepth;
930 112927 : assert(sd->vartop + n <= sd->varcount);
931 :
932 112927 : b->indepth = n;
933 112927 : b->invars = DMNEW(s4, n);
934 :
935 112927 : if (n) {
936 6698 : dv = sd->var + sd->vartop;
937 :
938 : /* allocate the invars */
939 :
940 15212 : for (i=0; i<n; ++i, ++dv) {
941 8514 : sv = sd->var + sd->bptr->outvars[i];
942 8514 : b->invars[i] = sd->vartop++;
943 8514 : dv->flags = INOUT;
944 8514 : COPY_VAL_AND_TYPE_VAR(sv, dv);
945 : }
946 : }
947 :
948 112927 : stack_create_locals(sd, b);
949 112927 : }
950 :
951 :
952 : /* stack_check_invars **********************************************************
953 :
954 : Check the current stack against the invars of the given basic block.
955 : Depth and types must match.
956 :
957 : IN:
958 : sd...........stack analysis data
959 : b............block which invars to check against
960 : curstack.....current stack top
961 : stackdepth...current stack depth
962 :
963 : RETURN VALUE:
964 : the destinaton block
965 : NULL.........a VerifyError has been thrown
966 :
967 : *******************************************************************************/
968 :
969 53595 : static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
970 : stackelement_t * curstack, int stackdepth)
971 : {
972 : int i;
973 : stackelement_t * sp;
974 : basicblock *orig;
975 : bool separable;
976 : varinfo *sv;
977 : varinfo *dv;
978 :
979 : #if defined(STACK_VERBOSE)
980 : printf("stack_check_invars(L%03d)\n", b->nr);
981 : #endif
982 :
983 : /* find original of b */
984 53595 : if (b->original)
985 0 : b = b->original;
986 53595 : orig = b;
987 :
988 : #if defined(STACK_VERBOSE)
989 : printf("original is L%03d\n", orig->nr);
990 : #endif
991 :
992 53595 : i = orig->indepth;
993 :
994 : #if defined(ENABLE_VERIFIER)
995 53595 : if (i != stackdepth) {
996 1 : exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
997 1 : return NULL;
998 : }
999 : #endif
1000 :
1001 5 : do {
1002 53594 : separable = false;
1003 :
1004 : #if defined(STACK_VERBOSE)
1005 : printf("checking against ");
1006 : stack_verbose_show_block(sd, b); printf("\n");
1007 : #endif
1008 :
1009 53594 : sp = curstack;
1010 74944 : for (i = orig->indepth; i--; sp = sp->prev) {
1011 21351 : dv = sd->var + b->invars[i];
1012 21351 : sv = sd->var + sp->varnum;
1013 :
1014 : #if defined(ENABLE_VERIFIER)
1015 21351 : if (dv->type != sp->type) {
1016 1 : exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1017 1 : return NULL;
1018 : }
1019 : #endif
1020 :
1021 21350 : if (sp->type == TYPE_RET) {
1022 : #if defined(ENABLE_VERIFIER)
1023 6 : if (dv->SBRSTART != sv->SBRSTART) {
1024 0 : exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1025 0 : return NULL;
1026 : }
1027 : #endif
1028 6 : if (dv->vv.retaddr != sv->vv.retaddr) {
1029 5 : separable = true;
1030 : /* don't break! have to check the remaining stackslots */
1031 : }
1032 : }
1033 : }
1034 :
1035 53593 : if (b->inlocals) {
1036 500685 : for (i=0; i<sd->localcount; ++i) {
1037 447093 : dv = b->inlocals + i;
1038 447093 : sv = sd->var + i;
1039 447093 : if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
1040 2 : if (
1041 : #if defined(ENABLE_VERIFIER)
1042 : (sv->SBRSTART == dv->SBRSTART) &&
1043 : #endif
1044 : (sv->vv.retaddr != dv->vv.retaddr))
1045 : {
1046 1 : separable = true;
1047 1 : break;
1048 : }
1049 : }
1050 : }
1051 : }
1052 :
1053 53593 : if (!separable) {
1054 : /* XXX cascading collapse? */
1055 :
1056 53588 : stack_merge_locals(sd, b);
1057 :
1058 : #if defined(STACK_VERBOSE)
1059 : printf("------> using L%03d\n", b->nr);
1060 : #endif
1061 53588 : return b;
1062 : }
1063 : } while ((b = b->copied_to) != NULL);
1064 :
1065 5 : b = stack_clone_block(sd, orig);
1066 5 : if (!b)
1067 0 : return NULL;
1068 :
1069 5 : stack_create_invars(sd, b, curstack, stackdepth);
1070 5 : return b;
1071 : }
1072 :
1073 :
1074 : /* stack_check_invars_from_outvars *********************************************
1075 :
1076 : Check the outvars of the current block against the invars of the given block.
1077 : Depth and types must match.
1078 :
1079 : IN:
1080 : sd...........stack analysis data
1081 : b............block which invars to check against
1082 :
1083 : RETURN VALUE:
1084 : the destinaton block
1085 : NULL.........a VerifyError has been thrown
1086 :
1087 : *******************************************************************************/
1088 :
1089 49848 : static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
1090 : {
1091 : int i;
1092 : int n;
1093 : varinfo *sv, *dv;
1094 : basicblock *orig;
1095 : bool separable;
1096 :
1097 : #if defined(STACK_VERBOSE)
1098 : printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
1099 : #endif
1100 :
1101 : /* find original of b */
1102 49848 : if (b->original)
1103 0 : b = b->original;
1104 49848 : orig = b;
1105 :
1106 : #if defined(STACK_VERBOSE)
1107 : printf("original is L%03d\n", orig->nr);
1108 : #endif
1109 :
1110 49848 : i = orig->indepth;
1111 49848 : n = sd->bptr->outdepth;
1112 :
1113 : #if defined(ENABLE_VERIFIER)
1114 49848 : if (i != n) {
1115 0 : exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
1116 0 : return NULL;
1117 : }
1118 : #endif
1119 :
1120 7 : do {
1121 49849 : separable = false;
1122 :
1123 : #if defined(STACK_VERBOSE)
1124 : printf("checking against ");
1125 : stack_verbose_show_block(sd, b); printf("\n");
1126 : #endif
1127 :
1128 49849 : if (n) {
1129 5574 : dv = sd->var + b->invars[0];
1130 :
1131 14801 : for (i=0; i<n; ++i, ++dv) {
1132 9228 : sv = sd->var + sd->bptr->outvars[i];
1133 :
1134 : #if defined(ENABLE_VERIFIER)
1135 9228 : if (sv->type != dv->type) {
1136 0 : exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1137 0 : return NULL;
1138 : }
1139 : #endif
1140 :
1141 9228 : if (dv->type == TYPE_RET) {
1142 : #if defined(ENABLE_VERIFIER)
1143 2 : if (sv->SBRSTART != dv->SBRSTART) {
1144 1 : exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1145 1 : return NULL;
1146 : }
1147 : #endif
1148 1 : if (sv->vv.retaddr != dv->vv.retaddr) {
1149 0 : separable = true;
1150 : /* don't break! have to check the remaining stackslots */
1151 : }
1152 : }
1153 : }
1154 : }
1155 :
1156 49848 : if (b->inlocals) {
1157 336401 : for (i=0; i<sd->localcount; ++i) {
1158 286560 : dv = b->inlocals + i;
1159 286560 : sv = sd->var + i;
1160 286560 : if (
1161 : #if defined(ENABLE_VERIFIER)
1162 : (sv->SBRSTART == dv->SBRSTART) &&
1163 : #endif
1164 : (sv->type == TYPE_RET && dv->type == TYPE_RET))
1165 : {
1166 9 : if (sv->vv.retaddr != dv->vv.retaddr) {
1167 7 : separable = true;
1168 7 : break;
1169 : }
1170 : }
1171 : }
1172 : }
1173 :
1174 49848 : if (!separable) {
1175 : /* XXX cascading collapse? */
1176 :
1177 49841 : stack_merge_locals(sd, b);
1178 :
1179 : #if defined(STACK_VERBOSE)
1180 : printf("------> using L%03d\n", b->nr);
1181 : #endif
1182 49841 : return b;
1183 : }
1184 : } while ((b = b->copied_to) != NULL);
1185 :
1186 6 : b = stack_clone_block(sd, orig);
1187 6 : if (!b)
1188 0 : return NULL;
1189 :
1190 6 : stack_create_invars_from_outvars(sd, b);
1191 6 : return b;
1192 : }
1193 :
1194 :
1195 : /* stack_create_instack ********************************************************
1196 :
1197 : Create the instack of the current basic block.
1198 :
1199 : IN:
1200 : sd...........stack analysis data
1201 :
1202 : RETURN VALUE:
1203 : the current stack top at the start of the basic block.
1204 :
1205 : *******************************************************************************/
1206 :
1207 319366 : static stackelement_t * stack_create_instack(stackdata_t *sd)
1208 : {
1209 : stackelement_t * sp;
1210 : int depth;
1211 : int index;
1212 :
1213 319366 : if ((depth = sd->bptr->indepth) == 0)
1214 295297 : return NULL;
1215 :
1216 24069 : sp = (sd->new_elem += depth);
1217 :
1218 79466 : while (depth--) {
1219 31328 : sp--;
1220 31328 : index = sd->bptr->invars[depth];
1221 31328 : sp->varnum = index;
1222 31328 : sp->type = sd->var[index].type;
1223 31328 : sp->prev = sp - 1;
1224 31328 : sp->creator = NULL;
1225 31328 : sp->flags = 0;
1226 31328 : sp->varkind = STACKVAR;
1227 : }
1228 24069 : sp->prev = NULL;
1229 :
1230 : /* return the top of the created stack */
1231 24069 : return sd->new_elem - 1;
1232 : }
1233 :
1234 :
1235 : /* stack_mark_reached **********************************************************
1236 :
1237 : Mark the given block reached and propagate the current stack and locals to
1238 : it. This function specializes the target block, if necessary, and returns
1239 : a pointer to the specialized target.
1240 :
1241 : IN:
1242 : sd...........stack analysis data
1243 : b............the block to reach
1244 : curstack.....the current stack top
1245 : stackdepth...the current stack depth
1246 :
1247 : RETURN VALUE:
1248 : a pointer to (a specialized version of) the target
1249 : NULL.........a VerifyError has been thrown
1250 :
1251 : *******************************************************************************/
1252 :
1253 173608 : static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackelement_t * curstack, int stackdepth)
1254 : {
1255 173608 : assert(b != NULL);
1256 :
1257 : #if defined(STACK_VERBOSE)
1258 : printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1259 : #endif
1260 :
1261 : /* mark targets of backward branches */
1262 :
1263 173608 : if (b->nr <= sd->bptr->nr)
1264 15014 : b->bitflags |= BBFLAG_REPLACEMENT;
1265 :
1266 173608 : if (b->state < basicblock::REACHED) {
1267 : /* b is reached for the first time. Create its invars. */
1268 :
1269 : #if defined(STACK_VERBOSE)
1270 : printf("reached L%03d for the first time\n", b->nr);
1271 : #endif
1272 :
1273 120013 : stack_create_invars(sd, b, curstack, stackdepth);
1274 :
1275 120013 : b->state = basicblock::REACHED;
1276 :
1277 120013 : return b;
1278 : }
1279 : else {
1280 : /* b has been reached before. Check that its invars match. */
1281 :
1282 53595 : return stack_check_invars(sd, b, curstack, stackdepth);
1283 : }
1284 : }
1285 :
1286 :
1287 : /* stack_mark_reached_from_outvars *********************************************
1288 :
1289 : Mark the given block reached and propagate the outvars of the current block
1290 : and the current locals to it. This function specializes the target block,
1291 : if necessary, and returns a pointer to the specialized target.
1292 :
1293 : IN:
1294 : sd...........stack analysis data
1295 : b............the block to reach
1296 :
1297 : RETURN VALUE:
1298 : a pointer to (a specialized version of) the target
1299 : NULL.........a VerifyError has been thrown
1300 :
1301 : *******************************************************************************/
1302 :
1303 162769 : static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1304 : {
1305 162769 : assert(b != NULL);
1306 :
1307 : #if defined(STACK_VERBOSE)
1308 : printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1309 : #endif
1310 :
1311 : /* mark targets of backward branches */
1312 :
1313 162769 : if (b->nr <= sd->bptr->nr)
1314 21 : b->bitflags |= BBFLAG_REPLACEMENT;
1315 :
1316 162769 : if (b->state < basicblock::REACHED) {
1317 : /* b is reached for the first time. Create its invars. */
1318 :
1319 : #if defined(STACK_VERBOSE)
1320 : printf("reached L%03d for the first time\n", b->nr);
1321 : #endif
1322 :
1323 112921 : stack_create_invars_from_outvars(sd, b);
1324 :
1325 112921 : b->state = basicblock::REACHED;
1326 :
1327 112921 : return b;
1328 : }
1329 : else {
1330 : /* b has been reached before. Check that its invars match. */
1331 :
1332 49848 : return stack_check_invars_from_outvars(sd, b);
1333 : }
1334 : }
1335 :
1336 :
1337 : /* stack_reach_next_block ******************************************************
1338 :
1339 : Mark the following block reached and propagate the outvars of the
1340 : current block and the current locals to it. This function
1341 : specializes the target block, if necessary, and returns a pointer
1342 : to the specialized target.
1343 :
1344 : IN:
1345 : sd...........stack analysis data
1346 :
1347 : RETURN VALUE:
1348 : a pointer to (a specialized version of) the following block
1349 : NULL.........a VerifyError has been thrown
1350 :
1351 : *******************************************************************************/
1352 :
1353 162741 : static bool stack_reach_next_block(stackdata_t *sd)
1354 : {
1355 : basicblock *tbptr;
1356 : instruction *iptr;
1357 :
1358 162741 : tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1359 162741 : tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1360 :
1361 162741 : if (tbptr == NULL)
1362 1 : return false;
1363 :
1364 162740 : if (tbptr != sd->bptr->next) {
1365 : #if defined(STACK_VERBOSE)
1366 : printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1367 : #endif
1368 3 : iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1369 3 : assert(iptr->opc == ICMD_NOP);
1370 3 : iptr->opc = ICMD_GOTO;
1371 3 : iptr->dst.block = tbptr;
1372 : #if defined(STACK_VERBOSE)
1373 : if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
1374 : #endif
1375 :
1376 3 : if (tbptr->state < basicblock::FINISHED)
1377 3 : sd->repeat = true; /* XXX check if we really need to repeat */
1378 : }
1379 :
1380 162740 : return true;
1381 : }
1382 :
1383 :
1384 : /* stack_reach_handlers ********************************************************
1385 :
1386 : Reach the exception handlers for the current block.
1387 :
1388 : IN:
1389 : sd...........stack analysis data
1390 :
1391 : RETURN VALUE:
1392 : true.........everything ok
1393 : false........a VerifyError has been thrown
1394 :
1395 : *******************************************************************************/
1396 :
1397 319409 : static bool stack_reach_handlers(stackdata_t *sd)
1398 : {
1399 : s4 i;
1400 : basicblock *tbptr;
1401 :
1402 : #if defined(STACK_VERBOSE)
1403 : printf("reaching exception handlers...\n");
1404 : #endif
1405 :
1406 350472 : for (i=0; sd->handlers[i]; ++i) {
1407 31063 : tbptr = sd->handlers[i]->handler;
1408 :
1409 31063 : tbptr->type = basicblock::TYPE_EXH;
1410 31063 : tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1411 :
1412 : /* reach (and specialize) the handler block */
1413 :
1414 31063 : tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1415 :
1416 31063 : if (tbptr == NULL)
1417 0 : return false;
1418 :
1419 31063 : sd->handlers[i]->handler = tbptr;
1420 : }
1421 :
1422 319409 : return true;
1423 : }
1424 :
1425 :
1426 : /* stack_reanalyse_block ******************************************************
1427 :
1428 : Re-analyse the current block. This is called if either the block itself
1429 : has already been analysed before, or the current block is a clone of an
1430 : already analysed block, and this clone is reached for the first time.
1431 : In the latter case, this function does all that is necessary for fully
1432 : cloning the block (cloning the instruction list and variables, etc.).
1433 :
1434 : IN:
1435 : sd...........stack analysis data
1436 :
1437 : RETURN VALUE:
1438 : true.........everything ok
1439 : false........a VerifyError has been thrown
1440 :
1441 : *******************************************************************************/
1442 :
1443 : #define RELOCATE(index) \
1444 : do { \
1445 : if ((index) >= blockvarstart) \
1446 : (index) += blockvarshift; \
1447 : else if ((index) >= invarstart) \
1448 : (index) += invarshift; \
1449 : } while (0)
1450 :
1451 43 : bool stack_reanalyse_block(stackdata_t *sd)
1452 : {
1453 : instruction *iptr;
1454 : basicblock *b;
1455 : basicblock *orig;
1456 : s4 len;
1457 : s4 invarstart;
1458 : s4 blockvarstart;
1459 : s4 invarshift;
1460 : s4 blockvarshift;
1461 : s4 i, varindex;
1462 : s4 *argp;
1463 : branch_target_t *table;
1464 : lookup_target_t *lookup;
1465 : bool superblockend;
1466 : bool cloneinstructions;
1467 : exception_entry *ex;
1468 :
1469 : #if defined(STACK_VERBOSE)
1470 : stack_verbose_block_enter(sd, true);
1471 : #endif
1472 :
1473 43 : b = sd->bptr;
1474 :
1475 43 : if (!b->iinstr) {
1476 11 : orig = b->original;
1477 11 : assert(orig != NULL);
1478 :
1479 : /* clone the instruction list */
1480 :
1481 11 : cloneinstructions = true;
1482 :
1483 11 : assert(orig->iinstr);
1484 11 : len = orig->icount;
1485 11 : iptr = DMNEW(instruction, len + 1);
1486 :
1487 11 : MCOPY(iptr, orig->iinstr, instruction, len);
1488 11 : iptr[len].opc = ICMD_NOP;
1489 11 : iptr[len].line = 0;
1490 11 : iptr[len].flags.bits = 0;
1491 11 : b->iinstr = iptr;
1492 11 : b->icount = ++len;
1493 :
1494 : /* reserve space for the clone's block variables */
1495 :
1496 11 : stack_grow_variable_array(sd, orig->varcount);
1497 :
1498 : /* we already have the invars set */
1499 :
1500 11 : assert(b->indepth == orig->indepth);
1501 :
1502 : /* calculate relocation shifts for invars and block variables */
1503 :
1504 11 : if (orig->indepth) {
1505 9 : invarstart = orig->invars[0];
1506 9 : invarshift = b->invars[0] - invarstart;
1507 : }
1508 : else {
1509 2 : invarstart = INT_MAX;
1510 2 : invarshift = 0;
1511 : }
1512 11 : blockvarstart = orig->varstart;
1513 11 : blockvarshift = sd->vartop - blockvarstart;
1514 :
1515 : /* copy block variables */
1516 :
1517 11 : b->varstart = sd->vartop;
1518 11 : b->varcount = orig->varcount;
1519 11 : sd->vartop += b->varcount;
1520 11 : MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1521 :
1522 : /* copy outvars */
1523 :
1524 11 : b->outdepth = orig->outdepth;
1525 11 : b->outvars = DMNEW(s4, orig->outdepth);
1526 11 : MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1527 :
1528 : /* clone exception handlers */
1529 :
1530 12 : for (i=0; sd->handlers[i]; ++i) {
1531 1 : ex = DNEW(exception_entry);
1532 1 : ex->handler = sd->handlers[i]->handler;
1533 1 : ex->start = b;
1534 1 : ex->end = b; /* XXX hack, see end of stack_analyse */
1535 1 : ex->catchtype = sd->handlers[i]->catchtype;
1536 1 : ex->down = NULL;
1537 :
1538 1 : assert(sd->extableend->down == NULL);
1539 1 : sd->extableend->down = ex;
1540 1 : sd->extableend = ex;
1541 1 : sd->jd->exceptiontablelength++;
1542 :
1543 1 : sd->handlers[i] = ex;
1544 : }
1545 : }
1546 : else {
1547 32 : cloneinstructions = false;
1548 32 : invarshift = 0;
1549 32 : blockvarshift = 0;
1550 32 : invarstart = sd->vartop;
1551 32 : blockvarstart = sd->vartop;
1552 32 : iptr = b->iinstr;
1553 : }
1554 :
1555 43 : if (b->original) {
1556 : /* find exception handlers for the cloned block */
1557 11 : len = 0;
1558 11 : ex = sd->jd->exceptiontable;
1559 18 : for (; ex != NULL; ex = ex->down) {
1560 : /* XXX the cloned exception handlers have identical */
1561 : /* start end end blocks. */
1562 7 : if ((ex->start == b) && (ex->end == b)) {
1563 1 : sd->handlers[len++] = ex;
1564 : }
1565 : }
1566 11 : sd->handlers[len] = NULL;
1567 : }
1568 :
1569 : #if defined(STACK_VERBOSE)
1570 : printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1571 : printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1572 : #endif
1573 :
1574 : /* mark block as finished */
1575 :
1576 43 : b->state = basicblock::FINISHED;
1577 :
1578 : /* initialize locals at the start of this block */
1579 :
1580 43 : if (b->inlocals)
1581 43 : MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1582 :
1583 43 : MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1584 :
1585 : /* reach exception handlers for this block */
1586 :
1587 43 : if (!stack_reach_handlers(sd))
1588 0 : return false;
1589 :
1590 43 : superblockend = false;
1591 :
1592 328 : for (len = b->icount; len--; iptr++) {
1593 : #if defined(STACK_VERBOSE)
1594 : show_icmd(sd->jd, iptr, false, SHOW_STACK);
1595 : printf("\n");
1596 : #endif
1597 :
1598 286 : switch (iptr->opc) {
1599 : case ICMD_RET:
1600 5 : varindex = iptr->s1.varindex;
1601 :
1602 : #if defined(ENABLE_VERIFIER)
1603 5 : if (sd->var[varindex].type != TYPE_RET) {
1604 1 : exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1605 1 : return false;
1606 : }
1607 : #endif
1608 :
1609 4 : iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1610 4 : superblockend = true;
1611 4 : break;
1612 :
1613 : case ICMD_JSR:
1614 1 : iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1615 1 : RELOCATE(iptr->dst.varindex);
1616 1 : superblockend = true;
1617 1 : break;
1618 :
1619 : case ICMD_RETURN:
1620 1 : superblockend = true;
1621 1 : break;
1622 :
1623 : case ICMD_CHECKNULL:
1624 : case ICMD_PUTSTATICCONST:
1625 0 : break;
1626 :
1627 : case ICMD_NOP:
1628 : case ICMD_IINC:
1629 44 : break;
1630 :
1631 : case ICMD_GOTO:
1632 7 : iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1633 7 : superblockend = true;
1634 7 : break;
1635 :
1636 : /* pop 0 push 1 const */
1637 :
1638 : case ICMD_ACONST:
1639 : case ICMD_ICONST:
1640 : case ICMD_LCONST:
1641 : case ICMD_FCONST:
1642 : case ICMD_DCONST:
1643 :
1644 : /* pop 0 push 1 load */
1645 :
1646 : case ICMD_ILOAD:
1647 : case ICMD_LLOAD:
1648 : case ICMD_FLOAD:
1649 : case ICMD_DLOAD:
1650 : case ICMD_ALOAD:
1651 82 : RELOCATE(iptr->dst.varindex);
1652 82 : break;
1653 :
1654 : /* pop 2 push 1 */
1655 :
1656 : case ICMD_IALOAD:
1657 : case ICMD_LALOAD:
1658 : case ICMD_FALOAD:
1659 : case ICMD_DALOAD:
1660 : case ICMD_AALOAD:
1661 : case ICMD_BALOAD:
1662 : case ICMD_CALOAD:
1663 : case ICMD_SALOAD:
1664 3 : RELOCATE(iptr->sx.s23.s2.varindex);
1665 3 : RELOCATE(iptr->s1.varindex);
1666 3 : RELOCATE(iptr->dst.varindex);
1667 3 : break;
1668 :
1669 : /* pop 3 push 0 */
1670 :
1671 : case ICMD_IASTORE:
1672 : case ICMD_LASTORE:
1673 : case ICMD_FASTORE:
1674 : case ICMD_DASTORE:
1675 : case ICMD_AASTORE:
1676 : case ICMD_BASTORE:
1677 : case ICMD_CASTORE:
1678 : case ICMD_SASTORE:
1679 0 : RELOCATE(iptr->sx.s23.s3.varindex);
1680 0 : RELOCATE(iptr->sx.s23.s2.varindex);
1681 0 : RELOCATE(iptr->s1.varindex);
1682 0 : break;
1683 :
1684 : /* pop 1 push 0 store */
1685 :
1686 : case ICMD_ISTORE:
1687 : case ICMD_LSTORE:
1688 : case ICMD_FSTORE:
1689 : case ICMD_DSTORE:
1690 : case ICMD_ASTORE:
1691 43 : RELOCATE(iptr->s1.varindex);
1692 :
1693 43 : varindex = iptr->dst.varindex;
1694 43 : COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1695 43 : i = iptr->sx.s23.s3.javaindex;
1696 43 : if (iptr->flags.bits & INS_FLAG_RETADDR) {
1697 : iptr->sx.s23.s2.retaddrnr =
1698 5 : JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1699 5 : sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1700 : }
1701 : else
1702 38 : sd->javalocals[i] = varindex;
1703 43 : if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1704 0 : sd->javalocals[i-1] = jitdata::UNUSED;
1705 43 : if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1706 1 : sd->javalocals[i+1] = jitdata::UNUSED;
1707 43 : break;
1708 :
1709 : /* pop 1 push 0 */
1710 :
1711 : case ICMD_ARETURN:
1712 : case ICMD_ATHROW:
1713 : case ICMD_IRETURN:
1714 : case ICMD_LRETURN:
1715 : case ICMD_FRETURN:
1716 : case ICMD_DRETURN:
1717 6 : RELOCATE(iptr->s1.varindex);
1718 6 : superblockend = true;
1719 6 : break;
1720 :
1721 : case ICMD_PUTSTATIC:
1722 : case ICMD_PUTFIELDCONST:
1723 : case ICMD_POP:
1724 2 : RELOCATE(iptr->s1.varindex);
1725 2 : break;
1726 :
1727 : /* pop 1 push 0 branch */
1728 :
1729 : case ICMD_IFNULL:
1730 : case ICMD_IFNONNULL:
1731 :
1732 : case ICMD_IFEQ:
1733 : case ICMD_IFNE:
1734 : case ICMD_IFLT:
1735 : case ICMD_IFGE:
1736 : case ICMD_IFGT:
1737 : case ICMD_IFLE:
1738 :
1739 : case ICMD_IF_LEQ:
1740 : case ICMD_IF_LNE:
1741 : case ICMD_IF_LLT:
1742 : case ICMD_IF_LGE:
1743 : case ICMD_IF_LGT:
1744 : case ICMD_IF_LLE:
1745 13 : RELOCATE(iptr->s1.varindex);
1746 13 : iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1747 13 : break;
1748 :
1749 : /* pop 1 push 0 table branch */
1750 :
1751 : case ICMD_TABLESWITCH:
1752 0 : i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1753 :
1754 0 : if (cloneinstructions) {
1755 0 : table = DMNEW(branch_target_t, i);
1756 0 : MCOPY(table, iptr->dst.table, branch_target_t, i);
1757 0 : iptr->dst.table = table;
1758 : }
1759 : else {
1760 0 : table = iptr->dst.table;
1761 : }
1762 :
1763 0 : RELOCATE(iptr->s1.varindex);
1764 0 : while (i--) {
1765 0 : table->block = stack_mark_reached_from_outvars(sd, table->block);
1766 0 : table++;
1767 : }
1768 0 : superblockend = true;
1769 0 : break;
1770 :
1771 : case ICMD_LOOKUPSWITCH:
1772 0 : i = iptr->sx.s23.s2.lookupcount;
1773 0 : if (cloneinstructions) {
1774 0 : lookup = DMNEW(lookup_target_t, i);
1775 0 : MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1776 0 : iptr->dst.lookup = lookup;
1777 : }
1778 : else {
1779 0 : lookup = iptr->dst.lookup;
1780 : }
1781 0 : RELOCATE(iptr->s1.varindex);
1782 0 : while (i--) {
1783 0 : lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1784 0 : lookup++;
1785 : }
1786 0 : iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1787 0 : superblockend = true;
1788 0 : break;
1789 :
1790 : case ICMD_MONITORENTER:
1791 : case ICMD_MONITOREXIT:
1792 0 : RELOCATE(iptr->s1.varindex);
1793 0 : break;
1794 :
1795 : /* pop 2 push 0 branch */
1796 :
1797 : case ICMD_IF_ICMPEQ:
1798 : case ICMD_IF_ICMPNE:
1799 : case ICMD_IF_ICMPLT:
1800 : case ICMD_IF_ICMPGE:
1801 : case ICMD_IF_ICMPGT:
1802 : case ICMD_IF_ICMPLE:
1803 :
1804 : case ICMD_IF_LCMPEQ:
1805 : case ICMD_IF_LCMPNE:
1806 : case ICMD_IF_LCMPLT:
1807 : case ICMD_IF_LCMPGE:
1808 : case ICMD_IF_LCMPGT:
1809 : case ICMD_IF_LCMPLE:
1810 :
1811 : case ICMD_IF_ACMPEQ:
1812 : case ICMD_IF_ACMPNE:
1813 3 : RELOCATE(iptr->sx.s23.s2.varindex);
1814 3 : RELOCATE(iptr->s1.varindex);
1815 3 : iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1816 3 : break;
1817 :
1818 : /* pop 2 push 0 */
1819 :
1820 : case ICMD_PUTFIELD:
1821 : case ICMD_IASTORECONST:
1822 : case ICMD_LASTORECONST:
1823 : case ICMD_AASTORECONST:
1824 : case ICMD_BASTORECONST:
1825 : case ICMD_CASTORECONST:
1826 : case ICMD_SASTORECONST:
1827 : case ICMD_POP2:
1828 0 : RELOCATE(iptr->sx.s23.s2.varindex);
1829 0 : RELOCATE(iptr->s1.varindex);
1830 0 : break;
1831 :
1832 : /* pop 0 push 1 copy */
1833 :
1834 : case ICMD_COPY:
1835 : case ICMD_MOVE:
1836 8 : RELOCATE(iptr->dst.varindex);
1837 8 : RELOCATE(iptr->s1.varindex);
1838 8 : COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1839 8 : break;
1840 :
1841 : /* pop 2 push 1 */
1842 :
1843 : case ICMD_IDIV:
1844 : case ICMD_IREM:
1845 : case ICMD_LDIV:
1846 : case ICMD_LREM:
1847 : case ICMD_IADD:
1848 : case ICMD_ISUB:
1849 : case ICMD_IMUL:
1850 : case ICMD_ISHL:
1851 : case ICMD_ISHR:
1852 : case ICMD_IUSHR:
1853 : case ICMD_IAND:
1854 : case ICMD_IOR:
1855 : case ICMD_IXOR:
1856 : case ICMD_LADD:
1857 : case ICMD_LSUB:
1858 : case ICMD_LMUL:
1859 : case ICMD_LOR:
1860 : case ICMD_LAND:
1861 : case ICMD_LXOR:
1862 : case ICMD_LSHL:
1863 : case ICMD_LSHR:
1864 : case ICMD_LUSHR:
1865 : case ICMD_FADD:
1866 : case ICMD_FSUB:
1867 : case ICMD_FMUL:
1868 : case ICMD_FDIV:
1869 : case ICMD_FREM:
1870 : case ICMD_DADD:
1871 : case ICMD_DSUB:
1872 : case ICMD_DMUL:
1873 : case ICMD_DDIV:
1874 : case ICMD_DREM:
1875 : case ICMD_LCMP:
1876 : case ICMD_FCMPL:
1877 : case ICMD_FCMPG:
1878 : case ICMD_DCMPL:
1879 : case ICMD_DCMPG:
1880 1 : RELOCATE(iptr->sx.s23.s2.varindex);
1881 1 : RELOCATE(iptr->s1.varindex);
1882 1 : RELOCATE(iptr->dst.varindex);
1883 1 : break;
1884 :
1885 : /* pop 1 push 1 */
1886 :
1887 : case ICMD_CHECKCAST:
1888 : case ICMD_ARRAYLENGTH:
1889 : case ICMD_INSTANCEOF:
1890 : case ICMD_NEWARRAY:
1891 : case ICMD_ANEWARRAY:
1892 : case ICMD_GETFIELD:
1893 : case ICMD_IADDCONST:
1894 : case ICMD_ISUBCONST:
1895 : case ICMD_IMULCONST:
1896 : case ICMD_IMULPOW2:
1897 : case ICMD_IDIVPOW2:
1898 : case ICMD_IREMPOW2:
1899 : case ICMD_IANDCONST:
1900 : case ICMD_IORCONST:
1901 : case ICMD_IXORCONST:
1902 : case ICMD_ISHLCONST:
1903 : case ICMD_ISHRCONST:
1904 : case ICMD_IUSHRCONST:
1905 : case ICMD_LADDCONST:
1906 : case ICMD_LSUBCONST:
1907 : case ICMD_LMULCONST:
1908 : case ICMD_LMULPOW2:
1909 : case ICMD_LDIVPOW2:
1910 : case ICMD_LREMPOW2:
1911 : case ICMD_LANDCONST:
1912 : case ICMD_LORCONST:
1913 : case ICMD_LXORCONST:
1914 : case ICMD_LSHLCONST:
1915 : case ICMD_LSHRCONST:
1916 : case ICMD_LUSHRCONST:
1917 : case ICMD_INEG:
1918 : case ICMD_INT2BYTE:
1919 : case ICMD_INT2CHAR:
1920 : case ICMD_INT2SHORT:
1921 : case ICMD_LNEG:
1922 : case ICMD_FNEG:
1923 : case ICMD_DNEG:
1924 : case ICMD_I2L:
1925 : case ICMD_I2F:
1926 : case ICMD_I2D:
1927 : case ICMD_L2I:
1928 : case ICMD_L2F:
1929 : case ICMD_L2D:
1930 : case ICMD_F2I:
1931 : case ICMD_F2L:
1932 : case ICMD_F2D:
1933 : case ICMD_D2I:
1934 : case ICMD_D2L:
1935 : case ICMD_D2F:
1936 15 : RELOCATE(iptr->s1.varindex);
1937 15 : RELOCATE(iptr->dst.varindex);
1938 15 : break;
1939 :
1940 : /* pop 0 push 1 */
1941 :
1942 : case ICMD_GETSTATIC:
1943 : case ICMD_NEW:
1944 2 : RELOCATE(iptr->dst.varindex);
1945 2 : break;
1946 :
1947 : /* pop many push any */
1948 :
1949 : case ICMD_INVOKESTATIC:
1950 : case ICMD_INVOKESPECIAL:
1951 : case ICMD_INVOKEVIRTUAL:
1952 : case ICMD_INVOKEINTERFACE:
1953 : case ICMD_BUILTIN:
1954 : case ICMD_MULTIANEWARRAY:
1955 50 : i = iptr->s1.argcount;
1956 50 : if (cloneinstructions) {
1957 5 : argp = DMNEW(s4, i);
1958 5 : MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1959 5 : iptr->sx.s23.s2.args = argp;
1960 : }
1961 : else {
1962 45 : argp = iptr->sx.s23.s2.args;
1963 : }
1964 :
1965 181 : while (--i >= 0) {
1966 81 : RELOCATE(*argp);
1967 81 : argp++;
1968 : }
1969 50 : RELOCATE(iptr->dst.varindex);
1970 50 : break;
1971 :
1972 : default:
1973 : exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1974 0 : iptr->opc);
1975 0 : return false;
1976 : } /* switch */
1977 :
1978 : #if defined(STACK_VERBOSE)
1979 : show_icmd(sd->jd, iptr, false, SHOW_STACK);
1980 : printf("\n");
1981 : #endif
1982 : }
1983 :
1984 : /* relocate outvars */
1985 :
1986 48 : for (i=0; i<b->outdepth; ++i) {
1987 6 : RELOCATE(b->outvars[i]);
1988 : }
1989 :
1990 : #if defined(STACK_VERBOSE)
1991 : stack_verbose_block_exit(sd, superblockend);
1992 : #endif
1993 :
1994 : /* propagate to the next block */
1995 :
1996 42 : if (!superblockend)
1997 23 : if (!stack_reach_next_block(sd))
1998 0 : return false;
1999 :
2000 42 : return true;
2001 : }
2002 :
2003 :
2004 : /* stack_change_to_tempvar *****************************************************
2005 :
2006 : Change the given stackslot to a TEMPVAR. This includes creating a new
2007 : temporary variable and changing the dst.varindex of the creator of the
2008 : stacklot to the new variable index. If this stackslot has been passed
2009 : through ICMDs between the point of its creation and the current point,
2010 : then the variable index is also changed in these ICMDs.
2011 :
2012 : IN:
2013 : sd...........stack analysis data
2014 : sp...........stackslot to change
2015 : ilimit.......instruction up to which to look for ICMDs passing-through
2016 : the stackslot (exclusive). This may point exactly after the
2017 : last instruction, in which case the search is done to the
2018 : basic block end.
2019 :
2020 : *******************************************************************************/
2021 :
2022 10647 : static void stack_change_to_tempvar(stackdata_t *sd, stackelement_t * sp,
2023 : instruction *ilimit)
2024 : {
2025 : s4 newindex;
2026 : s4 oldindex;
2027 : instruction *iptr;
2028 : s4 depth;
2029 : s4 i;
2030 :
2031 10647 : oldindex = sp->varnum;
2032 :
2033 : /* create a new temporary variable */
2034 :
2035 10647 : GET_NEW_VAR(*sd, newindex, sp->type);
2036 :
2037 10647 : sd->var[newindex].flags = sp->flags;
2038 :
2039 : /* change the stackslot */
2040 :
2041 10647 : sp->varnum = newindex;
2042 10647 : sp->varkind = TEMPVAR;
2043 :
2044 : /* change the dst.varindex of the stackslot's creator */
2045 :
2046 10647 : if (sp->creator)
2047 10647 : sp->creator->dst.varindex = newindex;
2048 :
2049 : /* handle ICMDs this stackslot passed through, if any */
2050 :
2051 10647 : if (sp->flags & PASSTHROUGH) {
2052 27 : iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
2053 :
2054 : /* assert that the limit points to an ICMD, or after the last one */
2055 :
2056 27 : assert(ilimit >= sd->bptr->iinstr);
2057 27 : assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
2058 :
2059 : /* find the stackdepth under sp plus one */
2060 : /* Note: This number is usually known when this function is called, */
2061 : /* but calculating it here is less error-prone and should not be */
2062 : /* a performance problem. */
2063 :
2064 60 : for (depth = 0; sp != NULL; sp = sp->prev)
2065 33 : depth++;
2066 :
2067 : /* iterate over all instructions in the range and replace */
2068 :
2069 214 : for (; iptr < ilimit; ++iptr) {
2070 187 : switch (iptr->opc) {
2071 : case ICMD_INVOKESTATIC:
2072 : case ICMD_INVOKESPECIAL:
2073 : case ICMD_INVOKEVIRTUAL:
2074 : case ICMD_INVOKEINTERFACE:
2075 : case ICMD_BUILTIN:
2076 30 : i = iptr->s1.argcount - depth;
2077 30 : if (iptr->sx.s23.s2.args[i] == oldindex) {
2078 30 : iptr->sx.s23.s2.args[i] = newindex;
2079 : }
2080 : break;
2081 : /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
2082 : /* stackslot, it must be added in this switch! */
2083 : default:
2084 : break;
2085 : }
2086 : }
2087 : }
2088 10647 : }
2089 :
2090 :
2091 : /* stack_init_javalocals *******************************************************
2092 :
2093 : Initialize the mapping from Java locals to cacao variables at method entry.
2094 :
2095 : IN:
2096 : sd...........stack analysis data
2097 :
2098 : *******************************************************************************/
2099 :
2100 86432 : static void stack_init_javalocals(stackdata_t *sd)
2101 : {
2102 86432 : jitdata *jd = sd->jd;
2103 86432 : s4 *jl = DMNEW(s4, sd->maxlocals);
2104 :
2105 86432 : jd->basicblocks[0].javalocals = jl;
2106 :
2107 291148 : for (int i=0; i<sd->maxlocals; ++i)
2108 204716 : jl[i] = jitdata::UNUSED;
2109 :
2110 86432 : methoddesc *md = jd->m->parseddesc;
2111 227713 : for (int i = 0, j = 0; i<md->paramcount; ++i) {
2112 141281 : Type type = md->paramtypes[i].type;
2113 141281 : jl[j] = jd->local_map[5*j + type];
2114 :
2115 141281 : j += IS_2_WORD_TYPE(type) ? 2 : 1;
2116 : }
2117 86432 : }
2118 :
2119 :
2120 : /* stack_analyse ***************************************************************
2121 :
2122 : Analyse_stack uses the intermediate code created by parse.c to
2123 : build a model of the JVM operand stack for the current method.
2124 :
2125 : The following checks are performed:
2126 : - check for operand stack underflow (before each instruction)
2127 : - check for operand stack overflow (after[1] each instruction)
2128 : - check for matching stack depth at merging points
2129 : - check for matching basic types[2] at merging points
2130 : - check basic types for instruction input (except for BUILTIN*
2131 : opcodes, INVOKE* opcodes and MULTIANEWARRAY)
2132 :
2133 : [1]) Checking this after the instruction should be ok. parse.c
2134 : counts the number of required stack slots in such a way that it is
2135 : only vital that we don't exceed `maxstack` at basic block
2136 : boundaries.
2137 :
2138 : [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2139 : DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2140 : types are not discerned.
2141 :
2142 : *******************************************************************************/
2143 :
2144 86432 : bool stack_analyse(jitdata *jd) {
2145 : stackdata_t sd;
2146 :
2147 86432 : return sd.analyse(jd);
2148 : }
2149 :
2150 86432 : bool stackdata_t::analyse(jitdata *jd)
2151 : {
2152 86432 : stackdata_t& sd = *this;
2153 :
2154 : methodinfo *m; /* method being analyzed */
2155 : codeinfo *code;
2156 : registerdata *rd;
2157 : int stackdepth;
2158 : stackelement_t *curstack; /* current stack top */
2159 : stackelement_t *copy;
2160 : ICMD opcode; /* opcode of current instruction */
2161 : int varindex;
2162 : int javaindex;
2163 : Type type; /* operand type */
2164 : int len; /* # of instructions after the current one */
2165 : bool superblockend; /* if true, no fallthrough to next block */
2166 : bool deadcode; /* true if no live code has been reached */
2167 : instruction *iptr; /* the current instruction */
2168 : basicblock *tbptr;
2169 : basicblock *original;
2170 :
2171 : stackelement_t **last_store_boundary;
2172 : stackelement_t *coalescing_boundary;
2173 :
2174 : stackelement_t *src1, *src2, *src3, *src4, *dst1, *dst2;
2175 :
2176 : branch_target_t *table;
2177 : lookup_target_t *lookup;
2178 : builtintable_entry *bte;
2179 : methoddesc *md;
2180 : #if defined(ENABLE_STATISTICS)
2181 : int iteration_count; /* number of iterations of analysis */
2182 : #endif
2183 : int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2184 :
2185 : #if defined(STACK_VERBOSE)
2186 : show_method(jd, SHOW_PARSE);
2187 : #endif
2188 :
2189 : /* get required compiler data - initialization */
2190 :
2191 86432 : m = jd->m;
2192 86432 : code = jd->code;
2193 86432 : rd = jd->rd;
2194 :
2195 : /* initialize the stackdata_t struct */
2196 :
2197 86432 : sd.m = m;
2198 86432 : sd.jd = jd;
2199 86432 : sd.varcount = jd->varcount;
2200 86432 : sd.vartop = jd->vartop;
2201 86432 : sd.localcount = jd->localcount;
2202 86432 : sd.var = jd->var;
2203 86432 : sd.varsallocated = sd.varcount;
2204 86432 : sd.maxlocals = m->maxlocals;
2205 86432 : sd.javalocals = DMNEW(s4, sd.maxlocals);
2206 86432 : sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2207 :
2208 : /* prepare the variable for exception handler stacks */
2209 : /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2210 :
2211 86432 : sd.exstack.type = TYPE_ADR;
2212 86432 : sd.exstack.prev = NULL;
2213 86432 : sd.exstack.varnum = sd.localcount;
2214 86432 : sd.var[sd.exstack.varnum].type = TYPE_ADR;
2215 :
2216 : #if defined(ENABLE_STATISTICS)
2217 : iteration_count = 0;
2218 : #endif
2219 :
2220 : /* find the last real basic block */
2221 :
2222 86432 : sd.last_real_block = NULL;
2223 86432 : tbptr = jd->basicblocks;
2224 492237 : while (tbptr->next) {
2225 319373 : sd.last_real_block = tbptr;
2226 319373 : tbptr = tbptr->next;
2227 : }
2228 86432 : assert(sd.last_real_block);
2229 :
2230 : /* find the last exception handler */
2231 :
2232 86432 : if (jd->exceptiontablelength)
2233 5555 : sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2234 : else
2235 80877 : sd.extableend = NULL;
2236 :
2237 : /* init jd->interface_map */
2238 :
2239 86432 : jd->maxinterfaces = m->maxstack;
2240 86432 : jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2241 1333367 : for (int i = 0; i < m->maxstack * 5; i++)
2242 1246935 : jd->interface_map[i].flags = jitdata::UNUSED;
2243 :
2244 86432 : last_store_boundary = DMNEW(stackelement_t *, m->maxlocals);
2245 :
2246 : /* initialize state and invars (none) of first block */
2247 :
2248 86432 : jd->basicblocks[0].state = basicblock::REACHED;
2249 86432 : jd->basicblocks[0].invars = NULL;
2250 86432 : jd->basicblocks[0].indepth = 0;
2251 86432 : jd->basicblocks[0].inlocals =
2252 86432 : DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2253 86432 : MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2254 172864 : jd->localcount + VERIFIER_EXTRA_LOCALS);
2255 :
2256 : /* initialize java local mapping of first block */
2257 :
2258 86432 : stack_init_javalocals(&sd);
2259 :
2260 : /* stack analysis loop (until fixpoint reached) **************************/
2261 :
2262 181213 : do {
2263 : #if defined(ENABLE_STATISTICS)
2264 : iteration_count++;
2265 : #endif
2266 :
2267 : /* initialize loop over basic blocks */
2268 :
2269 181229 : sd.bptr = jd->basicblocks;
2270 181229 : superblockend = true;
2271 181229 : sd.repeat = false;
2272 181229 : curstack = NULL;
2273 181229 : stackdepth = 0;
2274 181229 : deadcode = true;
2275 :
2276 : /* iterate over basic blocks *****************************************/
2277 :
2278 1123264 : for (; sd.bptr; sd.bptr = sd.bptr->next) {
2279 942051 : if (sd.bptr->state == basicblock::DELETED) {
2280 : /* This block has been deleted - do nothing. */
2281 :
2282 0 : continue;
2283 : }
2284 :
2285 942051 : if (sd.bptr->state == basicblock::TYPECHECK_REACHED) {
2286 : /* re-analyse a block because its input changed */
2287 :
2288 32 : deadcode = false;
2289 :
2290 32 : if (!stack_reanalyse_block(&sd))
2291 1 : return false;
2292 :
2293 31 : superblockend = true; /* XXX */
2294 31 : continue;
2295 : }
2296 :
2297 942019 : if (superblockend && (sd.bptr->state < basicblock::REACHED)) {
2298 : /* This block has not been reached so far, and we
2299 : don't fall into it, so we'll have to iterate
2300 : again. */
2301 :
2302 221310 : sd.repeat = true;
2303 221310 : continue;
2304 : }
2305 :
2306 720709 : if (sd.bptr->state > basicblock::REACHED) {
2307 : /* This block is already finished. */
2308 :
2309 401332 : superblockend = true;
2310 401332 : continue;
2311 : }
2312 :
2313 319377 : if (sd.bptr->original && sd.bptr->original->state < basicblock::FINISHED) {
2314 : /* This block is a clone and the original has not been
2315 : analysed, yet. Analyse it on the next
2316 : iteration. */
2317 :
2318 0 : sd.repeat = true;
2319 : /* XXX superblockend? */
2320 0 : continue;
2321 : }
2322 :
2323 : /* This block has to be analysed now. */
2324 :
2325 319377 : deadcode = false;
2326 :
2327 : /* XXX The rest of this block is still indented one level too */
2328 : /* much in order to avoid a giant diff by changing that. */
2329 :
2330 : /* We know that sd.bptr->state == BBREACHED. */
2331 : /* This block has been reached before. */
2332 :
2333 319377 : assert(sd.bptr->state == basicblock::REACHED);
2334 319377 : stackdepth = sd.bptr->indepth;
2335 :
2336 : /* find exception handlers for this block */
2337 :
2338 : /* determine the active exception handlers for this block */
2339 : /* XXX could use a faster algorithm with sorted lists or */
2340 : /* something? */
2341 :
2342 319377 : original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2343 :
2344 319377 : len = 0;
2345 621624 : for (exception_entry *ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
2346 302247 : if ((ex->start <= original) && (ex->end > original)) {
2347 31063 : sd.handlers[len++] = ex;
2348 : }
2349 : }
2350 319377 : sd.handlers[len] = NULL;
2351 :
2352 :
2353 : /* reanalyse cloned block */
2354 :
2355 319377 : if (sd.bptr->original) {
2356 11 : if (!stack_reanalyse_block(&sd))
2357 0 : return false;
2358 11 : continue;
2359 : }
2360 :
2361 : /* reset the new pointer for allocating stackslots */
2362 :
2363 319366 : sd.new_elem = jd->stack;
2364 :
2365 : /* create the instack of this block */
2366 :
2367 319366 : curstack = stack_create_instack(&sd);
2368 :
2369 : /* initialize locals at the start of this block */
2370 :
2371 319366 : if (sd.bptr->inlocals)
2372 319366 : MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2373 :
2374 319366 : MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2375 :
2376 : /* set up local variables for analyzing this block */
2377 :
2378 319366 : superblockend = false;
2379 319366 : len = sd.bptr->icount;
2380 319366 : iptr = sd.bptr->iinstr;
2381 :
2382 : /* mark the block as analysed */
2383 :
2384 319366 : sd.bptr->state = basicblock::FINISHED;
2385 :
2386 : /* reset variables for dependency checking */
2387 :
2388 319366 : coalescing_boundary = sd.new_elem;
2389 1811044 : for(int i = 0; i < m->maxlocals; i++)
2390 1491678 : last_store_boundary[i] = sd.new_elem;
2391 :
2392 : /* remember the start of this block's variables */
2393 :
2394 319366 : sd.bptr->varstart = sd.vartop;
2395 :
2396 : #if defined(STACK_VERBOSE)
2397 : stack_verbose_block_enter(&sd, false);
2398 : #endif
2399 :
2400 : /* reach exception handlers for this block */
2401 :
2402 319366 : if (!stack_reach_handlers(&sd))
2403 0 : return false;
2404 :
2405 : /* iterate over ICMDs ****************************************/
2406 :
2407 5051268 : while (--len >= 0) {
2408 :
2409 : #if defined(STACK_VERBOSE)
2410 : stack_verbose_show_state(&sd, iptr, curstack);
2411 : #endif
2412 :
2413 : /* fetch the current opcode */
2414 :
2415 4412550 : opcode = iptr->opc;
2416 :
2417 : /* automatically replace some ICMDs with builtins */
2418 :
2419 4412550 : bte = builtintable_get_automatic(opcode);
2420 :
2421 4412552 : if ((bte != NULL) && (bte->opcode == opcode)) {
2422 726 : iptr->opc = ICMD_BUILTIN;
2423 726 : iptr->flags.bits &= INS_FLAG_ID_MASK;
2424 726 : iptr->sx.s23.s3.bte = bte;
2425 : /* iptr->line is already set */
2426 726 : code_unflag_leafmethod(code);
2427 726 : goto icmd_BUILTIN;
2428 : }
2429 :
2430 : /* main opcode switch *************************************/
2431 :
2432 4411826 : switch (opcode) {
2433 :
2434 : /* pop 0 push 0 */
2435 :
2436 : case ICMD_NOP:
2437 : icmd_NOP:
2438 794010 : CLR_SX;
2439 794010 : OP0_0;
2440 794010 : break;
2441 :
2442 : case ICMD_CHECKNULL:
2443 0 : coalescing_boundary = sd.new_elem;
2444 : STATISTICS(count_check_null++);
2445 0 : USE_S1(TYPE_ADR);
2446 0 : CLR_SX;
2447 0 : iptr->dst.varindex = iptr->s1.varindex;
2448 0 : break;
2449 :
2450 : case ICMD_RET:
2451 : varindex = iptr->s1.varindex =
2452 19 : jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2453 :
2454 : #if defined(ENABLE_VERIFIER)
2455 19 : if (sd.var[varindex].type != TYPE_RET) {
2456 4 : exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2457 4 : return false;
2458 : }
2459 : #endif
2460 :
2461 15 : CLR_SX;
2462 :
2463 15 : iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2464 15 : superblockend = true;
2465 15 : break;
2466 :
2467 : case ICMD_RETURN:
2468 : STATISTICS(count_pcmd_return++);
2469 44368 : CLR_SX;
2470 44368 : OP0_0;
2471 44368 : superblockend = true;
2472 44368 : sd.jd->returncount++;
2473 44368 : sd.jd->returnblock = sd.bptr;
2474 44368 : break;
2475 :
2476 : case ICMD_BREAKPOINT:
2477 0 : OP0_0;
2478 0 : break;
2479 :
2480 :
2481 : /* pop 0 push 1 const */
2482 :
2483 : /************************** ICONST OPTIMIZATIONS **************************/
2484 :
2485 : case ICMD_ICONST:
2486 : STATISTICS(count_pcmd_load++);
2487 1208647 : if (len == 0)
2488 6 : goto normal_ICONST;
2489 :
2490 1208641 : switch (iptr[1].opc) {
2491 : case ICMD_IADD:
2492 8330 : iptr->opc = ICMD_IADDCONST;
2493 : /* FALLTHROUGH */
2494 :
2495 : icmd_iconst_tail:
2496 16418 : iptr[1].opc = ICMD_NOP;
2497 16418 : OP1_1(TYPE_INT, TYPE_INT);
2498 : STATISTICS(count_pcmd_op++);
2499 16418 : break;
2500 :
2501 : case ICMD_ISUB:
2502 4732 : iptr->opc = ICMD_ISUBCONST;
2503 4732 : goto icmd_iconst_tail;
2504 : #if SUPPORT_CONST_MUL
2505 : case ICMD_IMUL:
2506 866 : iptr->opc = ICMD_IMULCONST;
2507 866 : goto icmd_iconst_tail;
2508 : #else /* SUPPORT_CONST_MUL */
2509 : case ICMD_IMUL:
2510 : if (iptr->sx.val.i == 0x00000002)
2511 : iptr->sx.val.i = 1;
2512 : else if (iptr->sx.val.i == 0x00000004)
2513 : iptr->sx.val.i = 2;
2514 : else if (iptr->sx.val.i == 0x00000008)
2515 : iptr->sx.val.i = 3;
2516 : else if (iptr->sx.val.i == 0x00000010)
2517 : iptr->sx.val.i = 4;
2518 : else if (iptr->sx.val.i == 0x00000020)
2519 : iptr->sx.val.i = 5;
2520 : else if (iptr->sx.val.i == 0x00000040)
2521 : iptr->sx.val.i = 6;
2522 : else if (iptr->sx.val.i == 0x00000080)
2523 : iptr->sx.val.i = 7;
2524 : else if (iptr->sx.val.i == 0x00000100)
2525 : iptr->sx.val.i = 8;
2526 : else if (iptr->sx.val.i == 0x00000200)
2527 : iptr->sx.val.i = 9;
2528 : else if (iptr->sx.val.i == 0x00000400)
2529 : iptr->sx.val.i = 10;
2530 : else if (iptr->sx.val.i == 0x00000800)
2531 : iptr->sx.val.i = 11;
2532 : else if (iptr->sx.val.i == 0x00001000)
2533 : iptr->sx.val.i = 12;
2534 : else if (iptr->sx.val.i == 0x00002000)
2535 : iptr->sx.val.i = 13;
2536 : else if (iptr->sx.val.i == 0x00004000)
2537 : iptr->sx.val.i = 14;
2538 : else if (iptr->sx.val.i == 0x00008000)
2539 : iptr->sx.val.i = 15;
2540 : else if (iptr->sx.val.i == 0x00010000)
2541 : iptr->sx.val.i = 16;
2542 : else if (iptr->sx.val.i == 0x00020000)
2543 : iptr->sx.val.i = 17;
2544 : else if (iptr->sx.val.i == 0x00040000)
2545 : iptr->sx.val.i = 18;
2546 : else if (iptr->sx.val.i == 0x00080000)
2547 : iptr->sx.val.i = 19;
2548 : else if (iptr->sx.val.i == 0x00100000)
2549 : iptr->sx.val.i = 20;
2550 : else if (iptr->sx.val.i == 0x00200000)
2551 : iptr->sx.val.i = 21;
2552 : else if (iptr->sx.val.i == 0x00400000)
2553 : iptr->sx.val.i = 22;
2554 : else if (iptr->sx.val.i == 0x00800000)
2555 : iptr->sx.val.i = 23;
2556 : else if (iptr->sx.val.i == 0x01000000)
2557 : iptr->sx.val.i = 24;
2558 : else if (iptr->sx.val.i == 0x02000000)
2559 : iptr->sx.val.i = 25;
2560 : else if (iptr->sx.val.i == 0x04000000)
2561 : iptr->sx.val.i = 26;
2562 : else if (iptr->sx.val.i == 0x08000000)
2563 : iptr->sx.val.i = 27;
2564 : else if (iptr->sx.val.i == 0x10000000)
2565 : iptr->sx.val.i = 28;
2566 : else if (iptr->sx.val.i == 0x20000000)
2567 : iptr->sx.val.i = 29;
2568 : else if (iptr->sx.val.i == 0x40000000)
2569 : iptr->sx.val.i = 30;
2570 : else if (iptr->sx.val.u == 0x80000000)
2571 : iptr->sx.val.i = 31;
2572 : else
2573 : goto normal_ICONST;
2574 :
2575 : iptr->opc = ICMD_IMULPOW2;
2576 : goto icmd_iconst_tail;
2577 : #endif /* SUPPORT_CONST_MUL */
2578 : case ICMD_IDIV:
2579 55 : if (iptr->sx.val.i == 0x00000002)
2580 21 : iptr->sx.val.i = 1;
2581 34 : else if (iptr->sx.val.i == 0x00000004)
2582 1 : iptr->sx.val.i = 2;
2583 33 : else if (iptr->sx.val.i == 0x00000008)
2584 1 : iptr->sx.val.i = 3;
2585 32 : else if (iptr->sx.val.i == 0x00000010)
2586 1 : iptr->sx.val.i = 4;
2587 31 : else if (iptr->sx.val.i == 0x00000020)
2588 1 : iptr->sx.val.i = 5;
2589 30 : else if (iptr->sx.val.i == 0x00000040)
2590 1 : iptr->sx.val.i = 6;
2591 29 : else if (iptr->sx.val.i == 0x00000080)
2592 1 : iptr->sx.val.i = 7;
2593 28 : else if (iptr->sx.val.i == 0x00000100)
2594 1 : iptr->sx.val.i = 8;
2595 27 : else if (iptr->sx.val.i == 0x00000200)
2596 1 : iptr->sx.val.i = 9;
2597 26 : else if (iptr->sx.val.i == 0x00000400)
2598 1 : iptr->sx.val.i = 10;
2599 25 : else if (iptr->sx.val.i == 0x00000800)
2600 1 : iptr->sx.val.i = 11;
2601 24 : else if (iptr->sx.val.i == 0x00001000)
2602 1 : iptr->sx.val.i = 12;
2603 23 : else if (iptr->sx.val.i == 0x00002000)
2604 1 : iptr->sx.val.i = 13;
2605 22 : else if (iptr->sx.val.i == 0x00004000)
2606 1 : iptr->sx.val.i = 14;
2607 21 : else if (iptr->sx.val.i == 0x00008000)
2608 1 : iptr->sx.val.i = 15;
2609 20 : else if (iptr->sx.val.i == 0x00010000)
2610 1 : iptr->sx.val.i = 16;
2611 19 : else if (iptr->sx.val.i == 0x00020000)
2612 1 : iptr->sx.val.i = 17;
2613 18 : else if (iptr->sx.val.i == 0x00040000)
2614 1 : iptr->sx.val.i = 18;
2615 17 : else if (iptr->sx.val.i == 0x00080000)
2616 1 : iptr->sx.val.i = 19;
2617 16 : else if (iptr->sx.val.i == 0x00100000)
2618 1 : iptr->sx.val.i = 20;
2619 15 : else if (iptr->sx.val.i == 0x00200000)
2620 1 : iptr->sx.val.i = 21;
2621 14 : else if (iptr->sx.val.i == 0x00400000)
2622 1 : iptr->sx.val.i = 22;
2623 13 : else if (iptr->sx.val.i == 0x00800000)
2624 1 : iptr->sx.val.i = 23;
2625 12 : else if (iptr->sx.val.i == 0x01000000)
2626 1 : iptr->sx.val.i = 24;
2627 11 : else if (iptr->sx.val.i == 0x02000000)
2628 1 : iptr->sx.val.i = 25;
2629 10 : else if (iptr->sx.val.i == 0x04000000)
2630 1 : iptr->sx.val.i = 26;
2631 9 : else if (iptr->sx.val.i == 0x08000000)
2632 1 : iptr->sx.val.i = 27;
2633 8 : else if (iptr->sx.val.i == 0x10000000)
2634 1 : iptr->sx.val.i = 28;
2635 7 : else if (iptr->sx.val.i == 0x20000000)
2636 1 : iptr->sx.val.i = 29;
2637 6 : else if (iptr->sx.val.i == 0x40000000)
2638 1 : iptr->sx.val.i = 30;
2639 5 : else if (iptr->sx.val.u == 0x80000000)
2640 1 : iptr->sx.val.i = 31;
2641 : else
2642 4 : goto normal_ICONST;
2643 :
2644 51 : iptr->opc = ICMD_IDIVPOW2;
2645 51 : goto icmd_iconst_tail;
2646 :
2647 : case ICMD_IREM:
2648 : /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2649 1046 : if ((iptr->sx.val.i == 0x00000002) ||
2650 : (iptr->sx.val.i == 0x00000004) ||
2651 : (iptr->sx.val.i == 0x00000008) ||
2652 : (iptr->sx.val.i == 0x00000010) ||
2653 : (iptr->sx.val.i == 0x00000020) ||
2654 : (iptr->sx.val.i == 0x00000040) ||
2655 : (iptr->sx.val.i == 0x00000080) ||
2656 : (iptr->sx.val.i == 0x00000100) ||
2657 : (iptr->sx.val.i == 0x00000200) ||
2658 : (iptr->sx.val.i == 0x00000400) ||
2659 : (iptr->sx.val.i == 0x00000800) ||
2660 : (iptr->sx.val.i == 0x00001000) ||
2661 : (iptr->sx.val.i == 0x00002000) ||
2662 : (iptr->sx.val.i == 0x00004000) ||
2663 : (iptr->sx.val.i == 0x00008000) ||
2664 : (iptr->sx.val.i == 0x00010000) ||
2665 : (iptr->sx.val.i == 0x00020000) ||
2666 : (iptr->sx.val.i == 0x00040000) ||
2667 : (iptr->sx.val.i == 0x00080000) ||
2668 : (iptr->sx.val.i == 0x00100000) ||
2669 : (iptr->sx.val.i == 0x00200000) ||
2670 : (iptr->sx.val.i == 0x00400000) ||
2671 : (iptr->sx.val.i == 0x00800000) ||
2672 : (iptr->sx.val.i == 0x01000000) ||
2673 : (iptr->sx.val.i == 0x02000000) ||
2674 : (iptr->sx.val.i == 0x04000000) ||
2675 : (iptr->sx.val.i == 0x08000000) ||
2676 : (iptr->sx.val.i == 0x10000000) ||
2677 : (iptr->sx.val.i == 0x20000000) ||
2678 : (iptr->sx.val.i == 0x40000000) ||
2679 : (iptr->sx.val.u == 0x80000000))
2680 : {
2681 31 : iptr->opc = ICMD_IREMPOW2;
2682 31 : iptr->sx.val.i -= 1;
2683 31 : goto icmd_iconst_tail;
2684 : }
2685 1015 : goto normal_ICONST;
2686 : #if SUPPORT_CONST_LOGICAL
2687 : case ICMD_IAND:
2688 1231 : iptr->opc = ICMD_IANDCONST;
2689 1231 : goto icmd_iconst_tail;
2690 :
2691 : case ICMD_IOR:
2692 137 : iptr->opc = ICMD_IORCONST;
2693 137 : goto icmd_iconst_tail;
2694 :
2695 : case ICMD_IXOR:
2696 28 : iptr->opc = ICMD_IXORCONST;
2697 28 : goto icmd_iconst_tail;
2698 :
2699 : #endif /* SUPPORT_CONST_LOGICAL */
2700 : case ICMD_ISHL:
2701 499 : iptr->opc = ICMD_ISHLCONST;
2702 499 : goto icmd_iconst_tail;
2703 :
2704 : case ICMD_ISHR:
2705 185 : iptr->opc = ICMD_ISHRCONST;
2706 185 : goto icmd_iconst_tail;
2707 :
2708 : case ICMD_IUSHR:
2709 328 : iptr->opc = ICMD_IUSHRCONST;
2710 328 : goto icmd_iconst_tail;
2711 : #if SUPPORT_LONG_SHIFT
2712 : case ICMD_LSHL:
2713 16 : iptr->opc = ICMD_LSHLCONST;
2714 16 : goto icmd_lconst_tail;
2715 :
2716 : case ICMD_LSHR:
2717 25 : iptr->opc = ICMD_LSHRCONST;
2718 25 : goto icmd_lconst_tail;
2719 :
2720 : case ICMD_LUSHR:
2721 13 : iptr->opc = ICMD_LUSHRCONST;
2722 13 : goto icmd_lconst_tail;
2723 : #endif /* SUPPORT_LONG_SHIFT */
2724 : case ICMD_IF_ICMPEQ:
2725 3221 : iptr[1].opc = ICMD_IFEQ;
2726 : /* FALLTHROUGH */
2727 :
2728 : icmd_if_icmp_tail:
2729 : /* set the constant for the following icmd */
2730 14667 : iptr[1].sx.val.i = iptr->sx.val.i;
2731 :
2732 : /* this instruction becomes a nop */
2733 14667 : iptr->opc = ICMD_NOP;
2734 14667 : goto icmd_NOP;
2735 :
2736 : case ICMD_IF_ICMPLT:
2737 1439 : iptr[1].opc = ICMD_IFLT;
2738 1439 : goto icmd_if_icmp_tail;
2739 :
2740 : case ICMD_IF_ICMPLE:
2741 3467 : iptr[1].opc = ICMD_IFLE;
2742 3467 : goto icmd_if_icmp_tail;
2743 :
2744 : case ICMD_IF_ICMPNE:
2745 5325 : iptr[1].opc = ICMD_IFNE;
2746 5325 : goto icmd_if_icmp_tail;
2747 :
2748 : case ICMD_IF_ICMPGT:
2749 791 : iptr[1].opc = ICMD_IFGT;
2750 791 : goto icmd_if_icmp_tail;
2751 :
2752 : case ICMD_IF_ICMPGE:
2753 424 : iptr[1].opc = ICMD_IFGE;
2754 424 : goto icmd_if_icmp_tail;
2755 :
2756 : #if SUPPORT_CONST_STORE
2757 : case ICMD_IASTORE:
2758 : case ICMD_BASTORE:
2759 : case ICMD_CASTORE:
2760 : case ICMD_SASTORE:
2761 : # if SUPPORT_CONST_STORE_ZERO_ONLY
2762 : if (iptr->sx.val.i != 0)
2763 : goto normal_ICONST;
2764 : # endif
2765 514078 : switch (iptr[1].opc) {
2766 : case ICMD_IASTORE:
2767 4735 : iptr->opc = ICMD_IASTORECONST;
2768 4735 : iptr->flags.bits |= INS_FLAG_CHECK;
2769 4735 : break;
2770 : case ICMD_BASTORE:
2771 725 : iptr->opc = ICMD_BASTORECONST;
2772 725 : iptr->flags.bits |= INS_FLAG_CHECK;
2773 725 : break;
2774 : case ICMD_CASTORE:
2775 508614 : iptr->opc = ICMD_CASTORECONST;
2776 508614 : iptr->flags.bits |= INS_FLAG_CHECK;
2777 508614 : break;
2778 : case ICMD_SASTORE:
2779 4 : iptr->opc = ICMD_SASTORECONST;
2780 4 : iptr->flags.bits |= INS_FLAG_CHECK;
2781 : break;
2782 : default:
2783 : break;
2784 : }
2785 :
2786 514078 : iptr[1].opc = ICMD_NOP;
2787 :
2788 : /* copy the constant to s3 */
2789 : /* XXX constval -> astoreconstval? */
2790 514078 : iptr->sx.s23.s3.constval = iptr->sx.val.i;
2791 514078 : OP2_0(TYPE_ADR, TYPE_INT);
2792 : STATISTICS(count_pcmd_op++);
2793 514078 : break;
2794 :
2795 : case ICMD_PUTSTATIC:
2796 : case ICMD_PUTFIELD:
2797 : # if SUPPORT_CONST_STORE_ZERO_ONLY
2798 : if (iptr->sx.val.i != 0)
2799 : goto normal_ICONST;
2800 : # endif
2801 : /* XXX check field type? */
2802 :
2803 : /* copy the constant to s2 */
2804 : /* XXX constval -> fieldconstval? */
2805 8813 : iptr->sx.s23.s2.constval = iptr->sx.val.i;
2806 : // fallthrough!
2807 :
2808 : putconst_tail: {
2809 : constant_FMIref *fmiref;
2810 :
2811 : /* set the field reference (s3) */
2812 12946 : if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2813 0 : iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2814 0 : iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2815 0 : fmiref = iptr->sx.s23.s3.uf->fieldref;
2816 : }
2817 : else {
2818 12946 : fmiref = iptr[1].sx.s23.s3.fmiref;
2819 12946 : iptr->sx.s23.s3.fmiref = fmiref;
2820 : }
2821 :
2822 : #if defined(ENABLE_VERIFIER)
2823 12946 : Type expectedtype = fmiref->parseddesc.fd->type;
2824 12946 : switch (iptr[0].opc) {
2825 : case ICMD_ICONST:
2826 8813 : if (expectedtype != TYPE_INT)
2827 2 : return throw_stack_type_error(expectedtype);
2828 8811 : break;
2829 : case ICMD_LCONST:
2830 36 : if (expectedtype != TYPE_LNG)
2831 0 : return throw_stack_type_error(expectedtype);
2832 36 : break;
2833 : case ICMD_ACONST:
2834 4097 : if (expectedtype != TYPE_ADR)
2835 0 : return throw_stack_type_error(expectedtype);
2836 4097 : break;
2837 : default:
2838 0 : assert(false);
2839 : break;
2840 : }
2841 : #endif /* defined(ENABLE_VERIFIER) */
2842 :
2843 12944 : switch (iptr[1].opc) {
2844 : case ICMD_PUTSTATIC:
2845 814 : iptr->opc = ICMD_PUTSTATICCONST;
2846 814 : OP0_0;
2847 814 : break;
2848 : case ICMD_PUTFIELD:
2849 12130 : iptr->opc = ICMD_PUTFIELDCONST;
2850 12130 : OP1_0(TYPE_ADR);
2851 : break;
2852 : default:
2853 : break;
2854 : }
2855 :
2856 12943 : iptr[1].opc = ICMD_NOP;
2857 : STATISTICS(count_pcmd_op++);
2858 12943 : break;
2859 : }
2860 : #endif /* SUPPORT_CONST_STORE */
2861 :
2862 : default:
2863 653592 : goto normal_ICONST;
2864 : }
2865 :
2866 : /* if we get here, the ICONST has been optimized */
2867 543439 : break;
2868 :
2869 : normal_ICONST:
2870 : /* normal case of an unoptimized ICONST */
2871 654617 : OP0_1(TYPE_INT);
2872 654617 : break;
2873 :
2874 : /************************** LCONST OPTIMIZATIONS **************************/
2875 :
2876 : case ICMD_LCONST:
2877 : STATISTICS(count_pcmd_load++);
2878 6000 : if (len == 0)
2879 0 : goto normal_LCONST;
2880 :
2881 : /* switch depending on the following instruction */
2882 :
2883 6000 : switch (iptr[1].opc) {
2884 : #if SUPPORT_LONG_ADD
2885 : case ICMD_LADD:
2886 192 : iptr->opc = ICMD_LADDCONST;
2887 : /* FALLTHROUGH */
2888 :
2889 : icmd_lconst_tail:
2890 : /* instruction of type LONG -> LONG */
2891 428 : iptr[1].opc = ICMD_NOP;
2892 428 : OP1_1(TYPE_LNG, TYPE_LNG);
2893 : STATISTICS(count_pcmd_op++);
2894 428 : break;
2895 :
2896 : case ICMD_LSUB:
2897 31 : iptr->opc = ICMD_LSUBCONST;
2898 31 : goto icmd_lconst_tail;
2899 :
2900 : #endif /* SUPPORT_LONG_ADD */
2901 : #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2902 : case ICMD_LMUL:
2903 12 : iptr->opc = ICMD_LMULCONST;
2904 12 : goto icmd_lconst_tail;
2905 : #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2906 : # if SUPPORT_LONG_SHIFT
2907 : case ICMD_LMUL:
2908 : if (iptr->sx.val.l == 0x00000002)
2909 : iptr->sx.val.i = 1;
2910 : else if (iptr->sx.val.l == 0x00000004)
2911 : iptr->sx.val.i = 2;
2912 : else if (iptr->sx.val.l == 0x00000008)
2913 : iptr->sx.val.i = 3;
2914 : else if (iptr->sx.val.l == 0x00000010)
2915 : iptr->sx.val.i = 4;
2916 : else if (iptr->sx.val.l == 0x00000020)
2917 : iptr->sx.val.i = 5;
2918 : else if (iptr->sx.val.l == 0x00000040)
2919 : iptr->sx.val.i = 6;
2920 : else if (iptr->sx.val.l == 0x00000080)
2921 : iptr->sx.val.i = 7;
2922 : else if (iptr->sx.val.l == 0x00000100)
2923 : iptr->sx.val.i = 8;
2924 : else if (iptr->sx.val.l == 0x00000200)
2925 : iptr->sx.val.i = 9;
2926 : else if (iptr->sx.val.l == 0x00000400)
2927 : iptr->sx.val.i = 10;
2928 : else if (iptr->sx.val.l == 0x00000800)
2929 : iptr->sx.val.i = 11;
2930 : else if (iptr->sx.val.l == 0x00001000)
2931 : iptr->sx.val.i = 12;
2932 : else if (iptr->sx.val.l == 0x00002000)
2933 : iptr->sx.val.i = 13;
2934 : else if (iptr->sx.val.l == 0x00004000)
2935 : iptr->sx.val.i = 14;
2936 : else if (iptr->sx.val.l == 0x00008000)
2937 : iptr->sx.val.i = 15;
2938 : else if (iptr->sx.val.l == 0x00010000)
2939 : iptr->sx.val.i = 16;
2940 : else if (iptr->sx.val.l == 0x00020000)
2941 : iptr->sx.val.i = 17;
2942 : else if (iptr->sx.val.l == 0x00040000)
2943 : iptr->sx.val.i = 18;
2944 : else if (iptr->sx.val.l == 0x00080000)
2945 : iptr->sx.val.i = 19;
2946 : else if (iptr->sx.val.l == 0x00100000)
2947 : iptr->sx.val.i = 20;
2948 : else if (iptr->sx.val.l == 0x00200000)
2949 : iptr->sx.val.i = 21;
2950 : else if (iptr->sx.val.l == 0x00400000)
2951 : iptr->sx.val.i = 22;
2952 : else if (iptr->sx.val.l == 0x00800000)
2953 : iptr->sx.val.i = 23;
2954 : else if (iptr->sx.val.l == 0x01000000)
2955 : iptr->sx.val.i = 24;
2956 : else if (iptr->sx.val.l == 0x02000000)
2957 : iptr->sx.val.i = 25;
2958 : else if (iptr->sx.val.l == 0x04000000)
2959 : iptr->sx.val.i = 26;
2960 : else if (iptr->sx.val.l == 0x08000000)
2961 : iptr->sx.val.i = 27;
2962 : else if (iptr->sx.val.l == 0x10000000)
2963 : iptr->sx.val.i = 28;
2964 : else if (iptr->sx.val.l == 0x20000000)
2965 : iptr->sx.val.i = 29;
2966 : else if (iptr->sx.val.l == 0x40000000)
2967 : iptr->sx.val.i = 30;
2968 : else if (iptr->sx.val.l == 0x80000000)
2969 : iptr->sx.val.i = 31;
2970 : else {
2971 : goto normal_LCONST;
2972 : }
2973 : iptr->opc = ICMD_LMULPOW2;
2974 : goto icmd_lconst_tail;
2975 : # endif /* SUPPORT_LONG_SHIFT */
2976 : #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2977 : #if SUPPORT_LONG_DIV_POW2
2978 : case ICMD_LDIV:
2979 32 : if (iptr->sx.val.l == 0x00000002)
2980 1 : iptr->sx.val.i = 1;
2981 31 : else if (iptr->sx.val.l == 0x00000004)
2982 1 : iptr->sx.val.i = 2;
2983 30 : else if (iptr->sx.val.l == 0x00000008)
2984 1 : iptr->sx.val.i = 3;
2985 29 : else if (iptr->sx.val.l == 0x00000010)
2986 1 : iptr->sx.val.i = 4;
2987 28 : else if (iptr->sx.val.l == 0x00000020)
2988 1 : iptr->sx.val.i = 5;
2989 27 : else if (iptr->sx.val.l == 0x00000040)
2990 1 : iptr->sx.val.i = 6;
2991 26 : else if (iptr->sx.val.l == 0x00000080)
2992 1 : iptr->sx.val.i = 7;
2993 25 : else if (iptr->sx.val.l == 0x00000100)
2994 1 : iptr->sx.val.i = 8;
2995 24 : else if (iptr->sx.val.l == 0x00000200)
2996 1 : iptr->sx.val.i = 9;
2997 23 : else if (iptr->sx.val.l == 0x00000400)
2998 1 : iptr->sx.val.i = 10;
2999 22 : else if (iptr->sx.val.l == 0x00000800)
3000 1 : iptr->sx.val.i = 11;
3001 21 : else if (iptr->sx.val.l == 0x00001000)
3002 1 : iptr->sx.val.i = 12;
3003 20 : else if (iptr->sx.val.l == 0x00002000)
3004 1 : iptr->sx.val.i = 13;
3005 19 : else if (iptr->sx.val.l == 0x00004000)
3006 1 : iptr->sx.val.i = 14;
3007 18 : else if (iptr->sx.val.l == 0x00008000)
3008 1 : iptr->sx.val.i = 15;
3009 17 : else if (iptr->sx.val.l == 0x00010000)
3010 1 : iptr->sx.val.i = 16;
3011 16 : else if (iptr->sx.val.l == 0x00020000)
3012 1 : iptr->sx.val.i = 17;
3013 15 : else if (iptr->sx.val.l == 0x00040000)
3014 1 : iptr->sx.val.i = 18;
3015 14 : else if (iptr->sx.val.l == 0x00080000)
3016 1 : iptr->sx.val.i = 19;
3017 13 : else if (iptr->sx.val.l == 0x00100000)
3018 1 : iptr->sx.val.i = 20;
3019 12 : else if (iptr->sx.val.l == 0x00200000)
3020 1 : iptr->sx.val.i = 21;
3021 11 : else if (iptr->sx.val.l == 0x00400000)
3022 1 : iptr->sx.val.i = 22;
3023 10 : else if (iptr->sx.val.l == 0x00800000)
3024 1 : iptr->sx.val.i = 23;
3025 9 : else if (iptr->sx.val.l == 0x01000000)
3026 1 : iptr->sx.val.i = 24;
3027 8 : else if (iptr->sx.val.l == 0x02000000)
3028 1 : iptr->sx.val.i = 25;
3029 7 : else if (iptr->sx.val.l == 0x04000000)
3030 1 : iptr->sx.val.i = 26;
3031 6 : else if (iptr->sx.val.l == 0x08000000)
3032 1 : iptr->sx.val.i = 27;
3033 5 : else if (iptr->sx.val.l == 0x10000000)
3034 1 : iptr->sx.val.i = 28;
3035 4 : else if (iptr->sx.val.l == 0x20000000)
3036 1 : iptr->sx.val.i = 29;
3037 3 : else if (iptr->sx.val.l == 0x40000000)
3038 1 : iptr->sx.val.i = 30;
3039 2 : else if (iptr->sx.val.l == 0x80000000)
3040 0 : iptr->sx.val.i = 31;
3041 : else {
3042 2 : goto normal_LCONST;
3043 : }
3044 30 : iptr->opc = ICMD_LDIVPOW2;
3045 30 : goto icmd_lconst_tail;
3046 : #endif /* SUPPORT_LONG_DIV_POW2 */
3047 :
3048 : #if SUPPORT_LONG_REM_POW2
3049 : case ICMD_LREM:
3050 32 : if ((iptr->sx.val.l == 0x00000002) ||
3051 : (iptr->sx.val.l == 0x00000004) ||
3052 : (iptr->sx.val.l == 0x00000008) ||
3053 : (iptr->sx.val.l == 0x00000010) ||
3054 : (iptr->sx.val.l == 0x00000020) ||
3055 : (iptr->sx.val.l == 0x00000040) ||
3056 : (iptr->sx.val.l == 0x00000080) ||
3057 : (iptr->sx.val.l == 0x00000100) ||
3058 : (iptr->sx.val.l == 0x00000200) ||
3059 : (iptr->sx.val.l == 0x00000400) ||
3060 : (iptr->sx.val.l == 0x00000800) ||
3061 : (iptr->sx.val.l == 0x00001000) ||
3062 : (iptr->sx.val.l == 0x00002000) ||
3063 : (iptr->sx.val.l == 0x00004000) ||
3064 : (iptr->sx.val.l == 0x00008000) ||
3065 : (iptr->sx.val.l == 0x00010000) ||
3066 : (iptr->sx.val.l == 0x00020000) ||
3067 : (iptr->sx.val.l == 0x00040000) ||
3068 : (iptr->sx.val.l == 0x00080000) ||
3069 : (iptr->sx.val.l == 0x00100000) ||
3070 : (iptr->sx.val.l == 0x00200000) ||
3071 : (iptr->sx.val.l == 0x00400000) ||
3072 : (iptr->sx.val.l == 0x00800000) ||
3073 : (iptr->sx.val.l == 0x01000000) ||
3074 : (iptr->sx.val.l == 0x02000000) ||
3075 : (iptr->sx.val.l == 0x04000000) ||
3076 : (iptr->sx.val.l == 0x08000000) ||
3077 : (iptr->sx.val.l == 0x10000000) ||
3078 : (iptr->sx.val.l == 0x20000000) ||
3079 : (iptr->sx.val.l == 0x40000000) ||
3080 : (iptr->sx.val.l == 0x80000000))
3081 : {
3082 31 : iptr->opc = ICMD_LREMPOW2;
3083 31 : iptr->sx.val.l -= 1;
3084 31 : goto icmd_lconst_tail;
3085 : }
3086 1 : goto normal_LCONST;
3087 : #endif /* SUPPORT_LONG_REM_POW2 */
3088 :
3089 : #if SUPPORT_CONST_LOGICAL
3090 :
3091 : case ICMD_LAND:
3092 54 : iptr->opc = ICMD_LANDCONST;
3093 54 : goto icmd_lconst_tail;
3094 :
3095 : case ICMD_LOR:
3096 12 : iptr->opc = ICMD_LORCONST;
3097 12 : goto icmd_lconst_tail;
3098 :
3099 : case ICMD_LXOR:
3100 12 : iptr->opc = ICMD_LXORCONST;
3101 12 : goto icmd_lconst_tail;
3102 : #endif
3103 :
3104 : case ICMD_LCMP:
3105 295 : if ((len <= 1) || (iptr[2].sx.val.i != 0))
3106 : goto normal_LCONST;
3107 :
3108 : /* switch on the instruction after LCONST - LCMP */
3109 :
3110 295 : switch (iptr[2].opc) {
3111 : case ICMD_IFEQ:
3112 79 : iptr->opc = ICMD_IF_LEQ;
3113 : /* FALLTHROUGH */
3114 :
3115 : icmd_lconst_lcmp_tail:
3116 : /* convert LCONST, LCMP, IFXX to IF_LXX */
3117 295 : iptr->dst.block = iptr[2].dst.block;
3118 295 : iptr[1].opc = ICMD_NOP;
3119 295 : iptr[2].opc = ICMD_NOP;
3120 :
3121 295 : OP1_BRANCH(TYPE_LNG);
3122 295 : BRANCH(tbptr);
3123 : STATISTICS(count_pcmd_bra++);
3124 : STATISTICS(count_pcmd_op++);
3125 : break;
3126 :
3127 : case ICMD_IFNE:
3128 59 : iptr->opc = ICMD_IF_LNE;
3129 59 : goto icmd_lconst_lcmp_tail;
3130 :
3131 : case ICMD_IFLT:
3132 33 : iptr->opc = ICMD_IF_LLT;
3133 33 : goto icmd_lconst_lcmp_tail;
3134 :
3135 : case ICMD_IFGT:
3136 30 : iptr->opc = ICMD_IF_LGT;
3137 30 : goto icmd_lconst_lcmp_tail;
3138 :
3139 : case ICMD_IFLE:
3140 35 : iptr->opc = ICMD_IF_LLE;
3141 35 : goto icmd_lconst_lcmp_tail;
3142 :
3143 : case ICMD_IFGE:
3144 59 : iptr->opc = ICMD_IF_LGE;
3145 59 : goto icmd_lconst_lcmp_tail;
3146 :
3147 : default:
3148 0 : goto normal_LCONST;
3149 : } /* end switch on opcode after LCONST - LCMP */
3150 295 : break;
3151 :
3152 : #if SUPPORT_CONST_STORE
3153 : case ICMD_LASTORE:
3154 : # if SUPPORT_CONST_STORE_ZERO_ONLY
3155 : if (iptr->sx.val.l != 0)
3156 : goto normal_LCONST;
3157 : # endif
3158 : #if SIZEOF_VOID_P == 4
3159 : /* the constant must fit into a ptrint */
3160 : if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3161 : goto normal_LCONST;
3162 : #endif
3163 : /* move the constant to s3 */
3164 6 : iptr->sx.s23.s3.constval = iptr->sx.val.l;
3165 :
3166 6 : iptr->opc = ICMD_LASTORECONST;
3167 6 : iptr->flags.bits |= INS_FLAG_CHECK;
3168 6 : OP2_0(TYPE_ADR, TYPE_INT);
3169 :
3170 6 : iptr[1].opc = ICMD_NOP;
3171 : STATISTICS(count_pcmd_op++);
3172 6 : break;
3173 :
3174 : case ICMD_PUTSTATIC:
3175 : case ICMD_PUTFIELD:
3176 : # if SUPPORT_CONST_STORE_ZERO_ONLY
3177 : if (iptr->sx.val.l != 0)
3178 : goto normal_LCONST;
3179 : # endif
3180 : #if SIZEOF_VOID_P == 4
3181 : /* the constant must fit into a ptrint */
3182 : if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3183 : goto normal_LCONST;
3184 : #endif
3185 : /* XXX check field type? */
3186 :
3187 : /* copy the constant to s2 */
3188 : /* XXX constval -> fieldconstval? */
3189 36 : iptr->sx.s23.s2.constval = iptr->sx.val.l;
3190 :
3191 36 : goto putconst_tail;
3192 :
3193 : #endif /* SUPPORT_CONST_STORE */
3194 :
3195 : default:
3196 5286 : goto normal_LCONST;
3197 : } /* end switch opcode after LCONST */
3198 :
3199 : /* if we get here, the LCONST has been optimized */
3200 729 : break;
3201 :
3202 : normal_LCONST:
3203 : /* the normal case of an unoptimized LCONST */
3204 5289 : OP0_1(TYPE_LNG);
3205 5289 : break;
3206 :
3207 : /************************ END OF LCONST OPTIMIZATIONS *********************/
3208 :
3209 : case ICMD_FCONST:
3210 : STATISTICS(count_pcmd_load++);
3211 4946 : OP0_1(TYPE_FLT);
3212 4946 : break;
3213 :
3214 : case ICMD_DCONST:
3215 : STATISTICS(count_pcmd_load++);
3216 234 : OP0_1(TYPE_DBL);
3217 234 : break;
3218 :
3219 : /************************** ACONST OPTIMIZATIONS **************************/
3220 :
3221 : case ICMD_ACONST:
3222 169785 : coalescing_boundary = sd.new_elem;
3223 : STATISTICS(count_pcmd_load++);
3224 : #if SUPPORT_CONST_STORE
3225 : /* We can only optimize if the ACONST is resolved
3226 : * and there is an instruction after it. */
3227 :
3228 169785 : if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3229 : goto normal_ACONST;
3230 :
3231 137627 : switch (iptr[1].opc) {
3232 : case ICMD_AASTORE:
3233 : /* We can only optimize for NULL values
3234 : * here because otherwise a checkcast is
3235 : * required. */
3236 46503 : if (iptr->sx.val.anyptr != NULL)
3237 45917 : goto normal_ACONST;
3238 :
3239 : /* copy the constant (NULL) to s3 */
3240 586 : iptr->sx.s23.s3.constval = 0;
3241 586 : iptr->opc = ICMD_AASTORECONST;
3242 586 : iptr->flags.bits |= INS_FLAG_CHECK;
3243 586 : OP2_0(TYPE_ADR, TYPE_INT);
3244 :
3245 586 : iptr[1].opc = ICMD_NOP;
3246 : STATISTICS(count_pcmd_op++);
3247 : break;
3248 :
3249 : case ICMD_PUTSTATIC:
3250 : case ICMD_PUTFIELD:
3251 : # if SUPPORT_CONST_STORE_ZERO_ONLY
3252 : if (iptr->sx.val.anyptr != NULL)
3253 : goto normal_ACONST;
3254 : # endif
3255 : /* XXX check field type? */
3256 : /* copy the constant to s2 */
3257 : /* XXX constval -> fieldconstval? */
3258 4097 : iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3259 :
3260 4097 : goto putconst_tail;
3261 :
3262 : default:
3263 87027 : goto normal_ACONST;
3264 : }
3265 :
3266 : /* if we get here the ACONST has been optimized */
3267 586 : break;
3268 :
3269 : normal_ACONST:
3270 : #endif /* SUPPORT_CONST_STORE */
3271 165102 : OP0_1(TYPE_ADR);
3272 165102 : break;
3273 :
3274 :
3275 : /* pop 0 push 1 load */
3276 :
3277 : case ICMD_ILOAD:
3278 : case ICMD_LLOAD:
3279 : case ICMD_FLOAD:
3280 : case ICMD_DLOAD:
3281 : case ICMD_ALOAD:
3282 : STATISTICS(count_load_instruction++);
3283 512180 : type = (Type) (opcode - ICMD_ILOAD);
3284 :
3285 : varindex = iptr->s1.varindex =
3286 512180 : jd->local_map[iptr->s1.varindex * 5 + type];
3287 :
3288 : #if defined(ENABLE_VERIFIER)
3289 512180 : if (sd.var[varindex].type == TYPE_RET) {
3290 1 : exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3291 1 : return false;
3292 : }
3293 : #endif
3294 512179 : LOAD(type, varindex);
3295 512179 : break;
3296 :
3297 : /* pop 2 push 1 */
3298 :
3299 : case ICMD_LALOAD:
3300 : case ICMD_FALOAD:
3301 : case ICMD_DALOAD:
3302 : case ICMD_AALOAD:
3303 21272 : coalescing_boundary = sd.new_elem;
3304 21272 : iptr->flags.bits |= INS_FLAG_CHECK;
3305 : STATISTICS(count_check_null++);
3306 : STATISTICS(count_check_bound++);
3307 : STATISTICS(count_pcmd_mem++);
3308 21272 : OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3309 21272 : break;
3310 :
3311 : case ICMD_IALOAD:
3312 : case ICMD_BALOAD:
3313 : case ICMD_CALOAD:
3314 : case ICMD_SALOAD:
3315 4042 : coalescing_boundary = sd.new_elem;
3316 4042 : iptr->flags.bits |= INS_FLAG_CHECK;
3317 : STATISTICS(count_check_null++);
3318 : STATISTICS(count_check_bound++);
3319 : STATISTICS(count_pcmd_mem++);
3320 4042 : OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3321 4042 : break;
3322 :
3323 : /* pop 0 push 0 iinc */
3324 :
3325 : case ICMD_IINC: {
3326 : STATISTICS(count_store_depth[stackdepth]++);
3327 11445 : javaindex = iptr->s1.varindex;
3328 11445 : last_store_boundary[javaindex] = sd.new_elem;
3329 :
3330 : iptr->s1.varindex =
3331 11445 : jd->local_map[javaindex * 5 + TYPE_INT];
3332 :
3333 11445 : copy = curstack;
3334 15917 : for (int i = stackdepth - 1; copy; i--, copy = copy->prev) {
3335 6826 : if ((copy->varkind == LOCALVAR) &&
3336 2354 : (jd->reverselocalmap[copy->varnum] == javaindex))
3337 : {
3338 1513 : assert(IS_LOCALVAR(copy));
3339 1513 : SET_TEMPVAR(copy);
3340 : }
3341 : }
3342 :
3343 11445 : iptr->dst.varindex = iptr->s1.varindex;
3344 11445 : break;
3345 : }
3346 :
3347 : /* pop 1 push 0 store */
3348 :
3349 : case ICMD_ISTORE:
3350 : case ICMD_LSTORE:
3351 : case ICMD_FSTORE:
3352 : case ICMD_DSTORE:
3353 : case ICMD_ASTORE:
3354 95421 : REQUIRE(1);
3355 :
3356 95421 : type = (Type) (opcode - ICMD_ISTORE);
3357 95421 : javaindex = iptr->dst.varindex;
3358 : varindex = iptr->dst.varindex =
3359 95421 : jd->local_map[javaindex * 5 + type];
3360 :
3361 95421 : COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3362 :
3363 95421 : iptr->sx.s23.s3.javaindex = javaindex;
3364 :
3365 95421 : if (curstack->type == TYPE_RET) {
3366 21 : iptr->flags.bits |= INS_FLAG_RETADDR;
3367 : iptr->sx.s23.s2.retaddrnr =
3368 21 : JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3369 21 : sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3370 : }
3371 : else
3372 95400 : sd.javalocals[javaindex] = varindex;
3373 :
3374 : /* invalidate the following javalocal for 2-word types */
3375 :
3376 95421 : if (IS_2_WORD_TYPE(type)) {
3377 5229 : sd.javalocals[javaindex+1] = jitdata::UNUSED;
3378 5229 : iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3379 : }
3380 :
3381 : /* invalidate 2-word types if second half was overwritten */
3382 :
3383 95421 : if (javaindex > 0) {
3384 91222 : int i = sd.javalocals[javaindex-1];
3385 :
3386 91222 : if (i >= 0 && IS_2_WORD_TYPE(sd.var[i].type)) {
3387 3 : sd.javalocals[javaindex-1] = jitdata::UNUSED;
3388 3 : iptr->flags.bits |= INS_FLAG_KILL_PREV;
3389 : }
3390 : }
3391 :
3392 : STATISTICS(count_pcmd_store++);
3393 : STATISTICS(count_store_depth[stackdepth-1]++);
3394 : STATISTICS(count_store_length[sd.new_elem - curstack]++);
3395 :
3396 : /* check for conflicts as described in Figure 5.2 */
3397 :
3398 95421 : copy = curstack->prev;
3399 100211 : for (int i = stackdepth - 2; copy; i--, copy = copy->prev) {
3400 4952 : if ((copy->varkind == LOCALVAR) &&
3401 162 : (jd->reverselocalmap[copy->varnum] == javaindex))
3402 : {
3403 2 : assert(IS_LOCALVAR(copy));
3404 2 : SET_TEMPVAR(copy);
3405 : }
3406 : }
3407 :
3408 : /* if the variable is already coalesced, don't bother */
3409 :
3410 : /* We do not need to check against INOUT, as invars */
3411 : /* are always before the coalescing boundary. */
3412 :
3413 95421 : if (curstack->varkind == LOCALVAR)
3414 3150 : goto store_tail;
3415 :
3416 : /* there is no STORE Lj while curstack is live */
3417 :
3418 92271 : if (curstack < last_store_boundary[javaindex])
3419 5010 : goto assume_conflict;
3420 :
3421 : /* curstack must be after the coalescing boundary */
3422 :
3423 87261 : if (curstack < coalescing_boundary)
3424 7771 : goto assume_conflict;
3425 :
3426 : /* there is no DEF LOCALVAR(varindex) while curstack is live */
3427 :
3428 79490 : copy = sd.new_elem; /* most recent stackslot created + 1 */
3429 158982 : while (--copy > curstack) {
3430 3 : if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
3431 1 : goto assume_conflict;
3432 : }
3433 :
3434 : /* coalesce the temporary variable with Lj */
3435 : assert((curstack->varkind == TEMPVAR)
3436 79489 : || (curstack->varkind == UNDEFVAR));
3437 79489 : assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3438 79489 : assert(!IS_INOUT(curstack));
3439 79489 : assert(!IS_PREALLOC(curstack));
3440 :
3441 79489 : assert(curstack->creator);
3442 79489 : assert(curstack->creator->dst.varindex == curstack->varnum);
3443 79489 : assert(!(curstack->flags & PASSTHROUGH));
3444 : RELEASE_INDEX(sd, curstack);
3445 79489 : curstack->varkind = LOCALVAR;
3446 79489 : curstack->varnum = varindex;
3447 79489 : curstack->creator->dst.varindex = varindex;
3448 79489 : goto store_tail;
3449 :
3450 : /* revert the coalescing, if it has been done earlier */
3451 : assume_conflict:
3452 12782 : if ((curstack->varkind == LOCALVAR)
3453 0 : && (jd->reverselocalmap[curstack->varnum] == javaindex))
3454 : {
3455 0 : assert(IS_LOCALVAR(curstack));
3456 0 : SET_TEMPVAR(curstack);
3457 : }
3458 :
3459 : /* remember the stack boundary at this store */
3460 : store_tail:
3461 95421 : last_store_boundary[javaindex] = sd.new_elem;
3462 :
3463 95442 : if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3464 21 : STORE(TYPE_RET, varindex);
3465 : else
3466 95400 : STORE(opcode - ICMD_ISTORE, varindex);
3467 95421 : break;
3468 :
3469 : /* pop 3 push 0 */
3470 :
3471 : case ICMD_AASTORE:
3472 64566 : coalescing_boundary = sd.new_elem;
3473 64566 : iptr->flags.bits |= INS_FLAG_CHECK;
3474 : STATISTICS(count_check_null++);
3475 : STATISTICS(count_check_bound++);
3476 : STATISTICS(count_pcmd_mem++);
3477 :
3478 64566 : bte = builtintable_get_internal(BUILTIN_FAST_canstore);
3479 64566 : md = bte->md;
3480 :
3481 64566 : if (md->memuse > rd->memuse)
3482 0 : rd->memuse = md->memuse;
3483 64566 : if (md->argintreguse > rd->argintreguse)
3484 1 : rd->argintreguse = md->argintreguse;
3485 : /* XXX non-leaf method? */
3486 :
3487 : /* make all stack variables saved */
3488 :
3489 64566 : copy = curstack;
3490 446219 : while (copy) {
3491 317087 : sd.var[copy->varnum].flags |= SAVEDVAR;
3492 : /* in case copy->varnum is/will be a LOCALVAR */
3493 : /* once and set back to a non LOCALVAR */
3494 : /* the correct SAVEDVAR flag has to be */
3495 : /* remembered in copy->flags, too */
3496 317087 : copy->flags |= SAVEDVAR;
3497 317087 : copy = copy->prev;
3498 : }
3499 :
3500 64566 : OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3501 64566 : break;
3502 :
3503 :
3504 : case ICMD_LASTORE:
3505 : case ICMD_FASTORE:
3506 : case ICMD_DASTORE:
3507 20 : coalescing_boundary = sd.new_elem;
3508 20 : iptr->flags.bits |= INS_FLAG_CHECK;
3509 : STATISTICS(count_check_null++);
3510 : STATISTICS(count_check_bound++);
3511 : STATISTICS(count_pcmd_mem++);
3512 20 : OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3513 20 : break;
3514 :
3515 : case ICMD_IASTORE:
3516 : case ICMD_BASTORE:
3517 : case ICMD_CASTORE:
3518 : case ICMD_SASTORE:
3519 1530 : coalescing_boundary = sd.new_elem;
3520 1530 : iptr->flags.bits |= INS_FLAG_CHECK;
3521 : STATISTICS(count_check_null++);
3522 : STATISTICS(count_check_bound++);
3523 : STATISTICS(count_pcmd_mem++);
3524 1530 : OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3525 1530 : break;
3526 :
3527 : /* pop 1 push 0 */
3528 :
3529 : case ICMD_POP:
3530 : #ifdef ENABLE_VERIFIER
3531 16149 : if (opt_verify) {
3532 16149 : REQUIRE(1);
3533 16149 : if (IS_2_WORD_TYPE(curstack->type))
3534 0 : return throw_stack_category_error();
3535 : }
3536 : #endif
3537 16149 : OP1_0_ANY;
3538 16149 : break;
3539 :
3540 : case ICMD_IRETURN:
3541 : case ICMD_LRETURN:
3542 : case ICMD_FRETURN:
3543 : case ICMD_DRETURN:
3544 : case ICMD_ARETURN:
3545 58926 : coalescing_boundary = sd.new_elem;
3546 : /* Assert here that no LOCAL or INOUTS get */
3547 : /* preallocated, since tha macros are not */
3548 : /* available in md-abi.c! */
3549 58926 : if (IS_TEMPVAR(curstack))
3550 43733 : md_return_alloc(jd, curstack);
3551 : STATISTICS(count_pcmd_return++);
3552 58926 : OP1_0(opcode - ICMD_IRETURN);
3553 58926 : superblockend = true;
3554 58926 : sd.jd->returncount++;
3555 58926 : sd.jd->returnblock = sd.bptr;
3556 58926 : break;
3557 :
3558 : case ICMD_ATHROW:
3559 18424 : coalescing_boundary = sd.new_elem;
3560 : STATISTICS(count_check_null++);
3561 18424 : OP1_0(TYPE_ADR);
3562 18424 : curstack = NULL; stackdepth = 0;
3563 18424 : superblockend = true;
3564 18424 : break;
3565 :
3566 : case ICMD_PUTSTATIC: {
3567 21811 : coalescing_boundary = sd.new_elem;
3568 : STATISTICS(count_pcmd_mem++);
3569 : constant_FMIref *fmiref;
3570 21811 : INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3571 21811 : OP1_0(fmiref->parseddesc.fd->type);
3572 21810 : break;
3573 : }
3574 :
3575 : /* pop 1 push 0 branch */
3576 :
3577 : case ICMD_IFNULL:
3578 : case ICMD_IFNONNULL:
3579 : STATISTICS(count_pcmd_bra++);
3580 28821 : OP1_BRANCH(TYPE_ADR);
3581 28821 : BRANCH(tbptr);
3582 28821 : break;
3583 :
3584 : case ICMD_IFEQ:
3585 : case ICMD_IFNE:
3586 : case ICMD_IFLT:
3587 : case ICMD_IFGE:
3588 : case ICMD_IFGT:
3589 : case ICMD_IFLE:
3590 : STATISTICS(count_pcmd_bra++);
3591 : /* iptr->sx.val.i is set implicitly in parse by
3592 : clearing the memory or from IF_ICMPxx
3593 : optimization. */
3594 :
3595 57418 : OP1_BRANCH(TYPE_INT);
3596 : /* iptr->sx.val.i = 0; */
3597 57418 : BRANCH(tbptr);
3598 57418 : break;
3599 :
3600 : /* pop 0 push 0 branch */
3601 :
3602 : case ICMD_GOTO:
3603 : STATISTICS(count_pcmd_bra++);
3604 34740 : OP0_BRANCH;
3605 34740 : BRANCH(tbptr);
3606 34740 : superblockend = true;
3607 34740 : break;
3608 :
3609 : /* pop 1 push 0 table branch */
3610 :
3611 : case ICMD_TABLESWITCH: {
3612 : STATISTICS(count_pcmd_table++);
3613 72 : OP1_BRANCH(TYPE_INT);
3614 :
3615 72 : table = iptr->dst.table;
3616 72 : BRANCH_TARGET(*table, tbptr);
3617 72 : table++;
3618 :
3619 : int i = iptr->sx.s23.s3.tablehigh
3620 72 : - iptr->sx.s23.s2.tablelow + 1;
3621 :
3622 1218 : while (--i >= 0) {
3623 1074 : BRANCH_TARGET(*table, tbptr);
3624 1074 : table++;
3625 : }
3626 72 : superblockend = true;
3627 72 : break;
3628 : }
3629 :
3630 : /* pop 1 push 0 table branch */
3631 :
3632 : case ICMD_LOOKUPSWITCH: {
3633 : STATISTICS(count_pcmd_table++);
3634 60 : OP1_BRANCH(TYPE_INT);
3635 :
3636 60 : BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3637 :
3638 60 : lookup = iptr->dst.lookup;
3639 :
3640 60 : int i = iptr->sx.s23.s2.lookupcount;
3641 :
3642 600 : while (--i >= 0) {
3643 480 : BRANCH_TARGET(lookup->target, tbptr);
3644 480 : lookup++;
3645 : }
3646 60 : superblockend = true;
3647 60 : break;
3648 : }
3649 :
3650 : case ICMD_MONITORENTER:
3651 : case ICMD_MONITOREXIT:
3652 0 : coalescing_boundary = sd.new_elem;
3653 : STATISTICS(count_check_null++);
3654 0 : OP1_0(TYPE_ADR);
3655 0 : break;
3656 :
3657 : /* pop 2 push 0 branch */
3658 :
3659 : case ICMD_IF_ICMPEQ:
3660 : case ICMD_IF_ICMPNE:
3661 : case ICMD_IF_ICMPLT:
3662 : case ICMD_IF_ICMPGE:
3663 : case ICMD_IF_ICMPGT:
3664 : case ICMD_IF_ICMPLE:
3665 : STATISTICS(count_pcmd_bra++);
3666 16840 : OP2_BRANCH(TYPE_INT, TYPE_INT);
3667 16840 : BRANCH(tbptr);
3668 16840 : break;
3669 :
3670 : case ICMD_IF_ACMPEQ:
3671 : case ICMD_IF_ACMPNE:
3672 : STATISTICS(count_pcmd_bra++);
3673 2575 : OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3674 2575 : BRANCH(tbptr);
3675 2575 : break;
3676 :
3677 : /* pop 2 push 0 */
3678 :
3679 : case ICMD_PUTFIELD: {
3680 40114 : coalescing_boundary = sd.new_elem;
3681 : STATISTICS(count_check_null++);
3682 : STATISTICS(count_pcmd_mem++);
3683 : constant_FMIref *fmiref;
3684 40114 : INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3685 40114 : OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3686 40112 : break;
3687 : }
3688 :
3689 : case ICMD_POP2:
3690 158 : REQUIRE(1);
3691 158 : if (!IS_2_WORD_TYPE(curstack->type)) {
3692 : /* ..., cat1 */
3693 : #ifdef ENABLE_VERIFIER
3694 123 : if (opt_verify) {
3695 123 : REQUIRE(2);
3696 123 : if (IS_2_WORD_TYPE(curstack->prev->type))
3697 0 : return throw_stack_category_error();
3698 : }
3699 : #endif
3700 123 : OP2_0_ANY_ANY; /* pop two slots */
3701 : }
3702 : else {
3703 35 : iptr->opc = ICMD_POP;
3704 35 : OP1_0_ANY; /* pop one (two-word) slot */
3705 : }
3706 158 : break;
3707 :
3708 : /* pop 0 push 1 dup */
3709 :
3710 : case ICMD_DUP:
3711 : #ifdef ENABLE_VERIFIER
3712 639020 : if (opt_verify) {
3713 639020 : REQUIRE(1);
3714 639020 : if (IS_2_WORD_TYPE(curstack->type))
3715 0 : return throw_stack_category_error();
3716 : }
3717 : #endif
3718 : STATISTICS(count_dup_instruction++);
3719 :
3720 : icmd_DUP:
3721 639191 : src1 = curstack;
3722 :
3723 639191 : COPY_UP(src1);
3724 639191 : coalescing_boundary = sd.new_elem - 1;
3725 639191 : break;
3726 :
3727 : case ICMD_DUP2:
3728 247 : REQUIRE(1);
3729 247 : if (IS_2_WORD_TYPE(curstack->type)) {
3730 : /* ..., cat2 */
3731 171 : iptr->opc = ICMD_DUP;
3732 171 : goto icmd_DUP;
3733 : }
3734 : else {
3735 76 : REQUIRE(2);
3736 : /* ..., ????, cat1 */
3737 : #ifdef ENABLE_VERIFIER
3738 76 : if (opt_verify) {
3739 76 : if (IS_2_WORD_TYPE(curstack->prev->type))
3740 0 : return throw_stack_category_error();
3741 : }
3742 : #endif
3743 76 : src1 = curstack->prev;
3744 76 : src2 = curstack;
3745 :
3746 76 : COPY_UP(src1); iptr++; len--;
3747 76 : COPY_UP(src2);
3748 :
3749 76 : coalescing_boundary = sd.new_elem;
3750 : }
3751 76 : break;
3752 :
3753 : /* pop 2 push 3 dup */
3754 :
3755 : case ICMD_DUP_X1:
3756 : #ifdef ENABLE_VERIFIER
3757 2468 : if (opt_verify) {
3758 2468 : REQUIRE(2);
3759 2468 : if (IS_2_WORD_TYPE(curstack->type) ||
3760 : IS_2_WORD_TYPE(curstack->prev->type))
3761 0 : return throw_stack_category_error();
3762 : }
3763 : #endif
3764 :
3765 : icmd_DUP_X1:
3766 2473 : src1 = curstack->prev;
3767 2473 : src2 = curstack;
3768 2473 : POPANY; POPANY;
3769 2473 : stackdepth -= 2;
3770 :
3771 : /* move non-temporary sources out of the way */
3772 2473 : if (!IS_TEMPVAR(src2)) {
3773 442 : MOVE_TO_TEMP(src2); iptr++; len--;
3774 : }
3775 :
3776 2473 : DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3777 :
3778 2473 : MOVE_UP(src1); iptr++; len--;
3779 2473 : MOVE_UP(src2); iptr++; len--;
3780 :
3781 2473 : COPY_DOWN(curstack, dst1);
3782 :
3783 2473 : coalescing_boundary = sd.new_elem;
3784 2473 : break;
3785 :
3786 : case ICMD_DUP2_X1:
3787 66 : REQUIRE(2);
3788 66 : if (IS_2_WORD_TYPE(curstack->type)) {
3789 : /* ..., ????, cat2 */
3790 : #ifdef ENABLE_VERIFIER
3791 4 : if (opt_verify) {
3792 4 : if (IS_2_WORD_TYPE(curstack->prev->type))
3793 0 : return throw_stack_category_error();
3794 : }
3795 : #endif
3796 4 : iptr->opc = ICMD_DUP_X1;
3797 4 : goto icmd_DUP_X1;
3798 : }
3799 : else {
3800 : /* ..., ????, cat1 */
3801 : #ifdef ENABLE_VERIFIER
3802 62 : if (opt_verify) {
3803 62 : REQUIRE(3);
3804 62 : if (IS_2_WORD_TYPE(curstack->prev->type)
3805 : || IS_2_WORD_TYPE(curstack->prev->prev->type))
3806 0 : return throw_stack_category_error();
3807 : }
3808 : #endif
3809 :
3810 : icmd_DUP2_X1:
3811 62 : src1 = curstack->prev->prev;
3812 62 : src2 = curstack->prev;
3813 62 : src3 = curstack;
3814 62 : POPANY; POPANY; POPANY;
3815 62 : stackdepth -= 3;
3816 :
3817 : /* move non-temporary sources out of the way */
3818 62 : if (!IS_TEMPVAR(src2)) {
3819 1 : MOVE_TO_TEMP(src2); iptr++; len--;
3820 : }
3821 62 : if (!IS_TEMPVAR(src3)) {
3822 1 : MOVE_TO_TEMP(src3); iptr++; len--;
3823 : }
3824 :
3825 62 : DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3826 62 : DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3827 :
3828 62 : MOVE_UP(src1); iptr++; len--;
3829 62 : MOVE_UP(src2); iptr++; len--;
3830 62 : MOVE_UP(src3); iptr++; len--;
3831 :
3832 62 : COPY_DOWN(curstack, dst2); iptr++; len--;
3833 62 : COPY_DOWN(curstack->prev, dst1);
3834 :
3835 62 : coalescing_boundary = sd.new_elem;
3836 : }
3837 62 : break;
3838 :
3839 : /* pop 3 push 4 dup */
3840 :
3841 : case ICMD_DUP_X2:
3842 76 : REQUIRE(2);
3843 76 : if (IS_2_WORD_TYPE(curstack->prev->type)) {
3844 : /* ..., cat2, ???? */
3845 : #ifdef ENABLE_VERIFIER
3846 1 : if (opt_verify) {
3847 1 : if (IS_2_WORD_TYPE(curstack->type))
3848 0 : return throw_stack_category_error();
3849 : }
3850 : #endif
3851 1 : iptr->opc = ICMD_DUP_X1;
3852 1 : goto icmd_DUP_X1;
3853 : }
3854 : else {
3855 : /* ..., cat1, ???? */
3856 : #ifdef ENABLE_VERIFIER
3857 75 : if (opt_verify) {
3858 75 : REQUIRE(3);
3859 75 : if (IS_2_WORD_TYPE(curstack->type)
3860 : || IS_2_WORD_TYPE(curstack->prev->prev->type))
3861 0 : return throw_stack_category_error();
3862 : }
3863 : #endif
3864 : icmd_DUP_X2:
3865 75 : src1 = curstack->prev->prev;
3866 75 : src2 = curstack->prev;
3867 75 : src3 = curstack;
3868 75 : POPANY; POPANY; POPANY;
3869 75 : stackdepth -= 3;
3870 :
3871 : /* move non-temporary sources out of the way */
3872 75 : if (!IS_TEMPVAR(src2)) {
3873 14 : MOVE_TO_TEMP(src2); iptr++; len--;
3874 : }
3875 75 : if (!IS_TEMPVAR(src3)) {
3876 2 : MOVE_TO_TEMP(src3); iptr++; len--;
3877 : }
3878 :
3879 75 : DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3880 :
3881 75 : MOVE_UP(src1); iptr++; len--;
3882 75 : MOVE_UP(src2); iptr++; len--;
3883 75 : MOVE_UP(src3); iptr++; len--;
3884 :
3885 75 : COPY_DOWN(curstack, dst1);
3886 :
3887 75 : coalescing_boundary = sd.new_elem;
3888 : }
3889 75 : break;
3890 :
3891 : case ICMD_DUP2_X2:
3892 61 : REQUIRE(2);
3893 61 : if (IS_2_WORD_TYPE(curstack->type)) {
3894 : /* ..., ????, cat2 */
3895 0 : if (IS_2_WORD_TYPE(curstack->prev->type)) {
3896 : /* ..., cat2, cat2 */
3897 0 : iptr->opc = ICMD_DUP_X1;
3898 0 : goto icmd_DUP_X1;
3899 : }
3900 : else {
3901 : /* ..., cat1, cat2 */
3902 : #ifdef ENABLE_VERIFIER
3903 0 : if (opt_verify) {
3904 0 : REQUIRE(3);
3905 0 : if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3906 0 : return throw_stack_category_error();
3907 : }
3908 : #endif
3909 0 : iptr->opc = ICMD_DUP_X2;
3910 0 : goto icmd_DUP_X2;
3911 : }
3912 : }
3913 :
3914 61 : REQUIRE(3);
3915 : /* ..., ????, ????, cat1 */
3916 :
3917 61 : if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3918 : /* ..., cat2, ????, cat1 */
3919 : #ifdef ENABLE_VERIFIER
3920 0 : if (opt_verify) {
3921 0 : if (IS_2_WORD_TYPE(curstack->prev->type))
3922 0 : return throw_stack_category_error();
3923 : }
3924 : #endif
3925 0 : iptr->opc = ICMD_DUP2_X1;
3926 0 : goto icmd_DUP2_X1;
3927 : }
3928 : else {
3929 : /* ..., cat1, ????, cat1 */
3930 : #ifdef ENABLE_VERIFIER
3931 61 : if (opt_verify) {
3932 61 : REQUIRE(4);
3933 61 : if (IS_2_WORD_TYPE(curstack->prev->type)
3934 : || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3935 0 : return throw_stack_category_error();
3936 : }
3937 : #endif
3938 :
3939 61 : src1 = curstack->prev->prev->prev;
3940 61 : src2 = curstack->prev->prev;
3941 61 : src3 = curstack->prev;
3942 61 : src4 = curstack;
3943 61 : POPANY; POPANY; POPANY; POPANY;
3944 61 : stackdepth -= 4;
3945 :
3946 : /* move non-temporary sources out of the way */
3947 61 : if (!IS_TEMPVAR(src2)) {
3948 0 : MOVE_TO_TEMP(src2); iptr++; len--;
3949 : }
3950 61 : if (!IS_TEMPVAR(src3)) {
3951 0 : MOVE_TO_TEMP(src3); iptr++; len--;
3952 : }
3953 61 : if (!IS_TEMPVAR(src4)) {
3954 0 : MOVE_TO_TEMP(src4); iptr++; len--;
3955 : }
3956 :
3957 61 : DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3958 61 : DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3959 :
3960 61 : MOVE_UP(src1); iptr++; len--;
3961 61 : MOVE_UP(src2); iptr++; len--;
3962 61 : MOVE_UP(src3); iptr++; len--;
3963 61 : MOVE_UP(src4); iptr++; len--;
3964 :
3965 61 : COPY_DOWN(curstack, dst2); iptr++; len--;
3966 61 : COPY_DOWN(curstack->prev, dst1);
3967 :
3968 61 : coalescing_boundary = sd.new_elem;
3969 : }
3970 61 : break;
3971 :
3972 : /* pop 2 push 2 swap */
3973 :
3974 : case ICMD_SWAP:
3975 : #ifdef ENABLE_VERIFIER
3976 120 : if (opt_verify) {
3977 120 : REQUIRE(2);
3978 120 : if (IS_2_WORD_TYPE(curstack->type)
3979 : || IS_2_WORD_TYPE(curstack->prev->type))
3980 0 : return throw_stack_category_error();
3981 : }
3982 : #endif
3983 :
3984 120 : src1 = curstack->prev;
3985 120 : src2 = curstack;
3986 120 : POPANY; POPANY;
3987 120 : stackdepth -= 2;
3988 :
3989 : /* move non-temporary sources out of the way */
3990 120 : if (!IS_TEMPVAR(src1)) {
3991 8 : MOVE_TO_TEMP(src1); iptr++; len--;
3992 : }
3993 :
3994 120 : MOVE_UP(src2); iptr++; len--;
3995 120 : MOVE_UP(src1);
3996 :
3997 120 : coalescing_boundary = sd.new_elem;
3998 120 : break;
3999 :
4000 : /* pop 2 push 1 */
4001 :
4002 : case ICMD_IDIV:
4003 : case ICMD_IREM:
4004 1887 : coalescing_boundary = sd.new_elem;
4005 : #if !SUPPORT_DIVISION
4006 : bte = iptr->sx.s23.s3.bte;
4007 : md = bte->md;
4008 :
4009 : if (md->memuse > rd->memuse)
4010 : rd->memuse = md->memuse;
4011 : if (md->argintreguse > rd->argintreguse)
4012 : rd->argintreguse = md->argintreguse;
4013 :
4014 : /* make all stack variables saved */
4015 :
4016 : copy = curstack;
4017 : while (copy) {
4018 : sd.var[copy->varnum].flags |= SAVEDVAR;
4019 : copy->flags |= SAVEDVAR;
4020 : copy = copy->prev;
4021 : }
4022 : /* FALLTHROUGH */
4023 :
4024 : #endif /* !SUPPORT_DIVISION */
4025 :
4026 : case ICMD_ISHL:
4027 : case ICMD_ISHR:
4028 : case ICMD_IUSHR:
4029 : case ICMD_IADD:
4030 : case ICMD_ISUB:
4031 : case ICMD_IMUL:
4032 : case ICMD_IAND:
4033 : case ICMD_IOR:
4034 : case ICMD_IXOR:
4035 : STATISTICS(count_pcmd_op++);
4036 13598 : OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
4037 13598 : break;
4038 :
4039 : case ICMD_LDIV:
4040 : case ICMD_LREM:
4041 61 : coalescing_boundary = sd.new_elem;
4042 : #if !(SUPPORT_DIVISION && SUPPORT_LONG_DIV)
4043 : bte = iptr->sx.s23.s3.bte;
4044 : md = bte->md;
4045 :
4046 : if (md->memuse > rd->memuse)
4047 : rd->memuse = md->memuse;
4048 : if (md->argintreguse > rd->argintreguse)
4049 : rd->argintreguse = md->argintreguse;
4050 : /* XXX non-leaf method? */
4051 :
4052 : /* make all stack variables saved */
4053 :
4054 : copy = curstack;
4055 : while (copy) {
4056 : sd.var[copy->varnum].flags |= SAVEDVAR;
4057 : copy->flags |= SAVEDVAR;
4058 : copy = copy->prev;
4059 : }
4060 : /* FALLTHROUGH */
4061 :
4062 : #endif
4063 :
4064 : case ICMD_LMUL:
4065 : case ICMD_LADD:
4066 : case ICMD_LSUB:
4067 : case ICMD_LAND:
4068 : case ICMD_LOR:
4069 : case ICMD_LXOR:
4070 : STATISTICS(count_pcmd_op++);
4071 285 : OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
4072 285 : break;
4073 :
4074 : case ICMD_LSHL:
4075 : case ICMD_LSHR:
4076 : case ICMD_LUSHR:
4077 : STATISTICS(count_pcmd_op++);
4078 31 : OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
4079 31 : break;
4080 :
4081 : case ICMD_FADD:
4082 : case ICMD_FSUB:
4083 : case ICMD_FMUL:
4084 : case ICMD_FDIV:
4085 : case ICMD_FREM:
4086 : STATISTICS(count_pcmd_op++);
4087 2013 : OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
4088 2013 : break;
4089 :
4090 : case ICMD_DADD:
4091 : case ICMD_DSUB:
4092 : case ICMD_DMUL:
4093 : case ICMD_DDIV:
4094 : case ICMD_DREM:
4095 : STATISTICS(count_pcmd_op++);
4096 29 : OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
4097 29 : break;
4098 :
4099 : case ICMD_LCMP:
4100 : STATISTICS(count_pcmd_op++);
4101 125 : if ((len == 0) || (iptr[1].sx.val.i != 0))
4102 : goto normal_LCMP;
4103 :
4104 125 : switch (iptr[1].opc) {
4105 : case ICMD_IFEQ:
4106 4 : iptr->opc = ICMD_IF_LCMPEQ;
4107 : icmd_lcmp_if_tail:
4108 124 : iptr->dst.block = iptr[1].dst.block;
4109 124 : iptr[1].opc = ICMD_NOP;
4110 :
4111 124 : OP2_BRANCH(TYPE_LNG, TYPE_LNG);
4112 124 : BRANCH(tbptr);
4113 :
4114 : STATISTICS(count_pcmd_bra++);
4115 : break;
4116 : case ICMD_IFNE:
4117 17 : iptr->opc = ICMD_IF_LCMPNE;
4118 17 : goto icmd_lcmp_if_tail;
4119 : case ICMD_IFLT:
4120 19 : iptr->opc = ICMD_IF_LCMPLT;
4121 19 : goto icmd_lcmp_if_tail;
4122 : case ICMD_IFGT:
4123 8 : iptr->opc = ICMD_IF_LCMPGT;
4124 8 : goto icmd_lcmp_if_tail;
4125 : case ICMD_IFLE:
4126 32 : iptr->opc = ICMD_IF_LCMPLE;
4127 32 : goto icmd_lcmp_if_tail;
4128 : case ICMD_IFGE:
4129 44 : iptr->opc = ICMD_IF_LCMPGE;
4130 44 : goto icmd_lcmp_if_tail;
4131 : default:
4132 1 : goto normal_LCMP;
4133 : }
4134 124 : break;
4135 : normal_LCMP:
4136 1 : bte = builtintable_get_internal(BUILTIN_lcmp);
4137 :
4138 1 : iptr->opc = ICMD_BUILTIN;
4139 1 : iptr->flags.bits &= INS_FLAG_ID_MASK;
4140 1 : iptr->sx.s23.s3.bte = bte;
4141 : /* iptr->line is already set */
4142 1 : code_unflag_leafmethod(code);
4143 1 : goto icmd_BUILTIN;
4144 :
4145 : break;
4146 :
4147 : case ICMD_FCMPL:
4148 : case ICMD_FCMPG:
4149 : STATISTICS(count_pcmd_op++);
4150 1890 : OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4151 1890 : break;
4152 :
4153 : case ICMD_DCMPL:
4154 : case ICMD_DCMPG:
4155 : STATISTICS(count_pcmd_op++);
4156 57 : OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4157 57 : break;
4158 :
4159 : /* pop 1 push 1 */
4160 :
4161 : case ICMD_INEG:
4162 : case ICMD_INT2BYTE:
4163 : case ICMD_INT2CHAR:
4164 : case ICMD_INT2SHORT:
4165 : STATISTICS(count_pcmd_op++);
4166 2209 : OP1_1(TYPE_INT, TYPE_INT);
4167 2209 : break;
4168 : case ICMD_LNEG:
4169 : STATISTICS(count_pcmd_op++);
4170 50 : OP1_1(TYPE_LNG, TYPE_LNG);
4171 50 : break;
4172 : case ICMD_FNEG:
4173 : STATISTICS(count_pcmd_op++);
4174 0 : OP1_1(TYPE_FLT, TYPE_FLT);
4175 0 : break;
4176 : case ICMD_DNEG:
4177 : STATISTICS(count_pcmd_op++);
4178 0 : OP1_1(TYPE_DBL, TYPE_DBL);
4179 0 : break;
4180 :
4181 : case ICMD_I2L:
4182 : STATISTICS(count_pcmd_op++);
4183 370 : OP1_1(TYPE_INT, TYPE_LNG);
4184 370 : break;
4185 : case ICMD_I2F:
4186 : STATISTICS(count_pcmd_op++);
4187 1278 : OP1_1(TYPE_INT, TYPE_FLT);
4188 1278 : break;
4189 : case ICMD_I2D:
4190 : STATISTICS(count_pcmd_op++);
4191 8 : OP1_1(TYPE_INT, TYPE_DBL);
4192 8 : break;
4193 : case ICMD_L2I:
4194 : STATISTICS(count_pcmd_op++);
4195 267 : OP1_1(TYPE_LNG, TYPE_INT);
4196 267 : break;
4197 : case ICMD_L2F:
4198 : STATISTICS(count_pcmd_op++);
4199 1 : OP1_1(TYPE_LNG, TYPE_FLT);
4200 1 : break;
4201 : case ICMD_L2D:
4202 : STATISTICS(count_pcmd_op++);
4203 3 : OP1_1(TYPE_LNG, TYPE_DBL);
4204 3 : break;
4205 : case ICMD_F2I:
4206 : STATISTICS(count_pcmd_op++);
4207 0 : OP1_1(TYPE_FLT, TYPE_INT);
4208 0 : break;
4209 : case ICMD_F2L:
4210 : STATISTICS(count_pcmd_op++);
4211 0 : OP1_1(TYPE_FLT, TYPE_LNG);
4212 0 : break;
4213 : case ICMD_F2D:
4214 : STATISTICS(count_pcmd_op++);
4215 19 : OP1_1(TYPE_FLT, TYPE_DBL);
4216 19 : break;
4217 : case ICMD_D2I:
4218 : STATISTICS(count_pcmd_op++);
4219 0 : OP1_1(TYPE_DBL, TYPE_INT);
4220 0 : break;
4221 : case ICMD_D2L:
4222 : STATISTICS(count_pcmd_op++);
4223 0 : OP1_1(TYPE_DBL, TYPE_LNG);
4224 0 : break;
4225 : case ICMD_D2F:
4226 : STATISTICS(count_pcmd_op++);
4227 5 : OP1_1(TYPE_DBL, TYPE_FLT);
4228 5 : break;
4229 :
4230 : case ICMD_CHECKCAST:
4231 9191 : coalescing_boundary = sd.new_elem;
4232 9191 : if (iptr->flags.bits & INS_FLAG_ARRAY) {
4233 : /* array type cast-check */
4234 :
4235 959 : bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4236 959 : md = bte->md;
4237 :
4238 959 : if (md->memuse > rd->memuse)
4239 0 : rd->memuse = md->memuse;
4240 959 : if (md->argintreguse > rd->argintreguse)
4241 319 : rd->argintreguse = md->argintreguse;
4242 :
4243 : /* make all stack variables saved */
4244 :
4245 959 : copy = curstack;
4246 3205 : while (copy) {
4247 1287 : sd.var[copy->varnum].flags |= SAVEDVAR;
4248 1287 : copy->flags |= SAVEDVAR;
4249 1287 : copy = copy->prev;
4250 : }
4251 : }
4252 9191 : OP1_1(TYPE_ADR, TYPE_ADR);
4253 9191 : break;
4254 :
4255 : case ICMD_INSTANCEOF:
4256 : case ICMD_ARRAYLENGTH:
4257 10937 : coalescing_boundary = sd.new_elem;
4258 10937 : OP1_1(TYPE_ADR, TYPE_INT);
4259 10937 : break;
4260 :
4261 : case ICMD_NEWARRAY:
4262 : case ICMD_ANEWARRAY:
4263 0 : coalescing_boundary = sd.new_elem;
4264 0 : OP1_1(TYPE_INT, TYPE_ADR);
4265 0 : break;
4266 :
4267 : case ICMD_GETFIELD: {
4268 100195 : coalescing_boundary = sd.new_elem;
4269 : STATISTICS(count_check_null++);
4270 : STATISTICS(count_pcmd_mem++);
4271 : constant_FMIref *fmiref;
4272 100195 : INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4273 100195 : OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4274 100194 : break;
4275 : }
4276 :
4277 : /* pop 0 push 1 */
4278 :
4279 : case ICMD_GETSTATIC: {
4280 48509 : coalescing_boundary = sd.new_elem;
4281 : STATISTICS(count_pcmd_mem++);
4282 : constant_FMIref *fmiref;
4283 48509 : INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4284 48509 : OP0_1(fmiref->parseddesc.fd->type);
4285 48509 : break;
4286 : }
4287 :
4288 : case ICMD_NEW:
4289 0 : coalescing_boundary = sd.new_elem;
4290 0 : OP0_1(TYPE_ADR);
4291 0 : break;
4292 :
4293 : case ICMD_JSR:
4294 31 : OP0_1(TYPE_RET);
4295 :
4296 31 : tbptr = iptr->sx.s23.s3.jsrtarget.block;
4297 31 : tbptr->type = basicblock::TYPE_SBR;
4298 :
4299 31 : assert(sd.bptr->next); /* XXX exception */
4300 31 : sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4301 : #if defined(ENABLE_VERIFIER)
4302 31 : sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4303 : #endif
4304 :
4305 31 : tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4306 31 : if (tbptr == NULL)
4307 2 : return false;
4308 :
4309 29 : iptr->sx.s23.s3.jsrtarget.block = tbptr;
4310 :
4311 : /* We need to check for overflow right here because
4312 : * the pushed value is poped afterwards */
4313 29 : CHECKOVERFLOW;
4314 :
4315 29 : superblockend = true;
4316 : /* XXX should not be marked as interface, as it does not need to be */
4317 : /* allocated. Same for the invar of the target. */
4318 29 : break;
4319 :
4320 : /* pop many push any */
4321 :
4322 : case ICMD_BUILTIN:
4323 : icmd_BUILTIN: {
4324 77270 : builtintable_entry *bte = iptr->sx.s23.s3.bte;
4325 77270 : md = bte->md;
4326 77270 : goto _callhandling;
4327 : }
4328 :
4329 : case ICMD_INVOKESTATIC:
4330 : case ICMD_INVOKESPECIAL:
4331 : case ICMD_INVOKEVIRTUAL:
4332 : case ICMD_INVOKEINTERFACE:
4333 : STATISTICS(count_pcmd_met++);
4334 :
4335 : /* Check for functions to replace with builtin
4336 : * functions. */
4337 :
4338 283216 : if (builtintable_replace_function(iptr))
4339 1033 : goto icmd_BUILTIN;
4340 :
4341 282183 : INSTRUCTION_GET_METHODDESC(iptr, md);
4342 : /* XXX resurrect this COUNT? */
4343 : /* if (lm->flags & ACC_STATIC) */
4344 : /* {COUNT(count_check_null);} */
4345 :
4346 : _callhandling: {
4347 :
4348 359453 : coalescing_boundary = sd.new_elem;
4349 :
4350 359453 : const int paramcount = md->paramcount;
4351 :
4352 359453 : if (md->memuse > rd->memuse)
4353 1074 : rd->memuse = md->memuse;
4354 359453 : if (md->argintreguse > rd->argintreguse)
4355 109205 : rd->argintreguse = md->argintreguse;
4356 359453 : if (md->argfltreguse > rd->argfltreguse)
4357 56837 : rd->argfltreguse = md->argfltreguse;
4358 :
4359 359453 : REQUIRE(paramcount);
4360 :
4361 359453 : iptr->s1.argcount = stackdepth;
4362 359453 : iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4363 :
4364 359453 : copy = curstack;
4365 938066 : for (int i = paramcount - 1; i >= 0; i--) {
4366 578613 : iptr->sx.s23.s2.args[i] = copy->varnum;
4367 :
4368 : /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4369 : /* -> won't help anyway */
4370 578613 : if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4371 :
4372 : #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4373 : /* If we pass float arguments in integer argument registers, we
4374 : * are not allowed to precolor them here. Floats have to be moved
4375 : * to this regs explicitly in codegen().
4376 : * Only arguments that are passed by stack anyway can be precolored
4377 : * (michi 2005/07/24) */
4378 : if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4379 : (!IS_FLT_DBL_TYPE(copy->type)
4380 : || md->params[i].inmemory)) {
4381 : #else
4382 351255 : if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4383 : #endif
4384 :
4385 310611 : SET_PREALLOC(copy);
4386 :
4387 310611 : if (md->params[i].inmemory) {
4388 1068 : sd.var[copy->varnum].vv.regoff =
4389 1068 : md->params[i].regoff;
4390 : sd.var[copy->varnum].flags |=
4391 1068 : INMEMORY;
4392 : }
4393 : else {
4394 309543 : if (IS_FLT_DBL_TYPE(copy->type)) {
4395 : #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4396 : assert(0); /* XXX is this assert ok? */
4397 : #else
4398 4990 : sd.var[copy->varnum].vv.regoff =
4399 4990 : md->params[i].regoff;
4400 : #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4401 : }
4402 : else {
4403 : #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4404 : if (IS_2_WORD_TYPE(copy->type))
4405 : sd.var[copy->varnum].vv.regoff =
4406 : PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4407 : GET_HIGH_REG(md->params[i].regoff));
4408 :
4409 : else
4410 : #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4411 304553 : sd.var[copy->varnum].vv.regoff =
4412 304553 : md->params[i].regoff;
4413 : }
4414 : }
4415 : }
4416 : }
4417 578613 : copy = copy->prev;
4418 : }
4419 :
4420 : /* deal with live-through stack slots "under" the */
4421 : /* arguments */
4422 :
4423 588172 : for (int i = paramcount; copy; i++) {
4424 228719 : iptr->sx.s23.s2.args[i] = copy->varnum;
4425 228719 : sd.var[copy->varnum].flags |= SAVEDVAR;
4426 228719 : copy->flags |= SAVEDVAR | PASSTHROUGH;
4427 228719 : copy = copy->prev;
4428 : }
4429 :
4430 : /* pop the arguments */
4431 :
4432 359453 : int i = paramcount;
4433 :
4434 359453 : stackdepth -= i;
4435 1297519 : while (--i >= 0) {
4436 578613 : POPANY;
4437 : }
4438 :
4439 : /* push the return value */
4440 :
4441 359453 : if (md->returntype.type != TYPE_VOID) {
4442 241621 : GET_NEW_VAR(sd, new_index, md->returntype.type);
4443 241621 : DST(md->returntype.type, new_index);
4444 241621 : stackdepth++;
4445 : }
4446 359453 : break;
4447 : }
4448 :
4449 : case ICMD_MULTIANEWARRAY: {
4450 15 : coalescing_boundary = sd.new_elem;
4451 15 : if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4452 6 : rd->argintreguse = MIN(3, INT_ARG_CNT);
4453 :
4454 15 : int i = iptr->s1.argcount;
4455 :
4456 15 : REQUIRE(i);
4457 :
4458 15 : iptr->sx.s23.s2.args = DMNEW(s4, i);
4459 :
4460 : #if defined(SPECIALMEMUSE)
4461 : # if defined(__DARWIN__)
4462 : if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4463 : rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4464 : # else
4465 : if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4466 : rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4467 : # endif
4468 : #else
4469 : # if defined(__I386__)
4470 : if (rd->memuse < i + 3)
4471 : rd->memuse = i + 3; /* n integer args spilled on stack */
4472 : # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4473 : if (rd->memuse < i + 2)
4474 : rd->memuse = i + 2; /* 4*4 bytes callee save space */
4475 : # else
4476 15 : if (rd->memuse < i)
4477 7 : rd->memuse = i; /* n integer args spilled on stack */
4478 : # endif /* defined(__I386__) */
4479 : #endif
4480 15 : copy = curstack;
4481 67 : while (--i >= 0) {
4482 : /* check INT type here? Currently typecheck does this. */
4483 37 : iptr->sx.s23.s2.args[i] = copy->varnum;
4484 73 : if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4485 36 : && (!IS_INOUT(copy))
4486 : && (!IS_LOCALVAR(copy)) ) {
4487 33 : copy->varkind = ARGVAR;
4488 : sd.var[copy->varnum].flags |=
4489 33 : INMEMORY & PREALLOC;
4490 : #if defined(SPECIALMEMUSE)
4491 : # if defined(__DARWIN__)
4492 : sd.var[copy->varnum].vv.regoff = i +
4493 : LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4494 : # else
4495 : sd.var[copy->varnum].vv.regoff = i +
4496 : LA_SIZE_IN_POINTERS + 3;
4497 : # endif
4498 : #else
4499 : # if defined(__I386__)
4500 : sd.var[copy->varnum].vv.regoff = i + 3;
4501 : # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4502 : sd.var[copy->varnum].vv.regoff = i + 2;
4503 : # else
4504 33 : sd.var[copy->varnum].vv.regoff = i;
4505 : # endif /* defined(__I386__) */
4506 : #endif /* defined(SPECIALMEMUSE) */
4507 : }
4508 37 : copy = copy->prev;
4509 : }
4510 30 : while (copy) {
4511 0 : sd.var[copy->varnum].flags |= SAVEDVAR;
4512 0 : copy->flags |= SAVEDVAR;
4513 0 : copy = copy->prev;
4514 : }
4515 :
4516 15 : i = iptr->s1.argcount;
4517 15 : stackdepth -= i;
4518 67 : while (--i >= 0) {
4519 37 : POPANY;
4520 : }
4521 15 : GET_NEW_VAR(sd, new_index, TYPE_ADR);
4522 15 : DST(TYPE_ADR, new_index);
4523 15 : stackdepth++;
4524 15 : break;
4525 : }
4526 :
4527 : default:
4528 : exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4529 0 : opcode);
4530 0 : return false;
4531 : } /* switch */
4532 :
4533 4412538 : CHECKOVERFLOW;
4534 4412536 : iptr++;
4535 : } /* while instructions */
4536 :
4537 : /* show state after last instruction */
4538 :
4539 : #if defined(STACK_VERBOSE)
4540 : stack_verbose_show_state(&sd, NULL, curstack);
4541 : #endif
4542 :
4543 : /* stack slots at basic block end become interfaces */
4544 :
4545 319352 : sd.bptr->outdepth = stackdepth;
4546 319352 : sd.bptr->outvars = DMNEW(s4, stackdepth);
4547 :
4548 319352 : int i = stackdepth - 1;
4549 346685 : for (copy = curstack; copy; i--, copy = copy->prev) {
4550 : varinfo *v;
4551 :
4552 : /* with the new vars rd->interfaces will be removed */
4553 : /* and all in and outvars have to be STACKVARS! */
4554 : /* in the moment i.e. SWAP with in and out vars can */
4555 : /* create an unresolvable conflict */
4556 :
4557 27333 : SET_TEMPVAR(copy);
4558 27333 : type = copy->type;
4559 :
4560 27333 : v = sd.var + copy->varnum;
4561 27333 : v->flags |= INOUT;
4562 :
4563 : /* do not allocate variables for returnAddresses */
4564 :
4565 27333 : if (type != TYPE_RET) {
4566 27296 : if (jd->interface_map[i*5 + type].flags == jitdata::UNUSED) {
4567 : /* no interface var until now for this depth and */
4568 : /* type */
4569 10560 : jd->interface_map[i*5 + type].flags = v->flags;
4570 : }
4571 : else {
4572 16736 : jd->interface_map[i*5 + type].flags |= v->flags;
4573 : }
4574 : }
4575 :
4576 27333 : sd.bptr->outvars[i] = copy->varnum;
4577 : }
4578 :
4579 : /* check if interface slots at basic block begin must be saved */
4580 :
4581 350675 : for (int i=0; i<sd.bptr->indepth; ++i) {
4582 31323 : varinfo *v = sd.var + sd.bptr->invars[i];
4583 :
4584 31323 : type = v->type;
4585 :
4586 31323 : if (type != TYPE_RET) {
4587 31294 : if (jd->interface_map[i*5 + type].flags == jitdata::UNUSED) {
4588 : /* no interface var until now for this depth and */
4589 : /* type */
4590 2999 : jd->interface_map[i*5 + type].flags = v->flags;
4591 : }
4592 : else {
4593 28295 : jd->interface_map[i*5 + type].flags |= v->flags;
4594 : }
4595 : }
4596 : }
4597 :
4598 : /* store the number of this block's variables */
4599 :
4600 319352 : sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4601 :
4602 : #if defined(STACK_VERBOSE)
4603 : stack_verbose_block_exit(&sd, superblockend);
4604 : #endif
4605 :
4606 : /* reach the following block, if any */
4607 :
4608 319352 : if (!superblockend)
4609 162718 : if (!stack_reach_next_block(&sd))
4610 1 : return false;
4611 :
4612 : } /* for blocks */
4613 :
4614 : } while (sd.repeat && !deadcode);
4615 :
4616 : /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4617 :
4618 : /* A local variable may be used as both a returnAddress and a reference */
4619 : /* type variable, as we do not split variables between these types when */
4620 : /* renaming locals. While returnAddresses have been eliminated now, we */
4621 : /* must assume that the variable is still used as TYPE_ADR. */
4622 : /* The only way that a local can be TYPE_VOID at this point, is that it */
4623 : /* was a TYPE_RET variable for which incompatible returnAddresses were */
4624 : /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4625 : /* here. */
4626 : /* XXX: It would be nice to remove otherwise unused returnAddress */
4627 : /* variables from the local variable array, so they are not */
4628 : /* allocated by simplereg. (For LSRA this is not needed). */
4629 :
4630 281827 : for (int i=0; i<sd.localcount; ++i) {
4631 195411 : if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4632 11 : sd.var[i].type = TYPE_ADR;
4633 : }
4634 :
4635 : /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4636 :
4637 2503924 : for (int i=sd.localcount; i<sd.vartop; ++i) {
4638 2417508 : if (sd.var[i].type == TYPE_RET)
4639 43 : sd.var[i].flags |= PREALLOC;
4640 : }
4641 :
4642 : /* XXX hack to fix up the ranges of the cloned single-block handlers */
4643 :
4644 100108 : for (exception_entry *ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
4645 13692 : if (ex->start == ex->end) {
4646 1 : assert(ex->end->next);
4647 1 : ex->end = ex->end->next;
4648 : }
4649 : }
4650 :
4651 : /* store number of created variables */
4652 :
4653 86416 : jd->vartop = sd.vartop;
4654 :
4655 : /* gather statistics *****************************************************/
4656 :
4657 : STATISTICS(count_max_basic_blocks.max(jd->basicblockcount));
4658 : STATISTICS(count_basic_blocks += jd->basicblockcount);
4659 : STATISTICS(count_max_javainstr.max(jd->instructioncount));
4660 : STATISTICS(count_javainstr += jd->instructioncount);
4661 : STATISTICS(count_upper_bound_new_stack.max(jd->stackcount));
4662 : STATISTICS(count_max_new_stack.max(sd.new_elem - jd->stack));
4663 :
4664 : STATISTICS(count_analyse_iterations[iteration_count]++);
4665 : STATISTICS(count_method_bb_distribution[jd->basicblockcount]++);
4666 : #if defined(ENABLE_STATISTICS)
4667 : sd.bptr = jd->basicblocks;
4668 : for (; sd.bptr; sd.bptr = sd.bptr->next) {
4669 : if (sd.bptr->state > basicblock::REACHED) {
4670 : STATISTICS(count_block_stack[sd.bptr->indepth]++);
4671 : STATISTICS(count_block_size_distribution[sd.bptr->icount]++);
4672 : }
4673 : }
4674 : #endif /* defined(ENABLE_STATISTICS) */
4675 :
4676 : /* everything's ok *******************************************************/
4677 :
4678 86416 : return true;
4679 : }
4680 :
4681 :
4682 : /* stack_javalocals_store ******************************************************
4683 :
4684 : Model the effect of a ?STORE instruction upon the given javalocals array.
4685 :
4686 : IN:
4687 : iptr.............the ?STORE instruction
4688 : javalocals.......the javalocals array to modify
4689 :
4690 : *******************************************************************************/
4691 :
4692 0 : void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4693 : {
4694 0 : s4 varindex = iptr->dst.varindex; // index into the jd->var array
4695 0 : s4 javaindex = iptr->sx.s23.s3.javaindex; // java local index
4696 :
4697 0 : if (javaindex != jitdata::UNUSED) {
4698 0 : assert(javaindex >= 0);
4699 0 : if (iptr->flags.bits & INS_FLAG_RETADDR)
4700 0 : javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4701 : else
4702 0 : javalocals[javaindex] = varindex;
4703 :
4704 0 : if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4705 0 : javalocals[javaindex-1] = jitdata::UNUSED;
4706 :
4707 0 : if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4708 0 : javalocals[javaindex+1] = jitdata::UNUSED;
4709 : }
4710 0 : }
4711 :
4712 :
4713 : /* functions for verbose stack analysis output ********************************/
4714 :
4715 : #if defined(STACK_VERBOSE)
4716 : static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4717 : {
4718 : printf("%c", show_jit_type_letters[v->type]);
4719 : if (v->type == TYPE_RET) {
4720 : printf("{L%03d}", v->vv.retaddr->nr);
4721 : #if defined(ENABLE_VERIFIER)
4722 : printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4723 : #endif
4724 : }
4725 : }
4726 :
4727 :
4728 : static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4729 : {
4730 : assert(index >= 0 && index < sd->vartop);
4731 : stack_verbose_show_varinfo(sd, sd->var + index);
4732 : }
4733 :
4734 :
4735 : static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4736 : {
4737 : s4 i;
4738 :
4739 : printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4740 : if (bptr->invars) {
4741 : for (i=0; i<bptr->indepth; ++i) {
4742 : if (i)
4743 : putchar(' ');
4744 : stack_verbose_show_variable(sd, bptr->invars[i]);
4745 : }
4746 : }
4747 : else
4748 : putchar('-');
4749 : printf("] javalocals ");
4750 : show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4751 : printf(" inlocals [");
4752 : if (bptr->inlocals) {
4753 : for (i=0; i<sd->localcount; ++i) {
4754 : if (i)
4755 : putchar(' ');
4756 : stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4757 : }
4758 : }
4759 : else
4760 : putchar('-');
4761 : printf("] out:%d [", bptr->outdepth);
4762 : if (bptr->outvars) {
4763 : for (i=0; i<bptr->outdepth; ++i) {
4764 : if (i)
4765 : putchar(' ');
4766 : stack_verbose_show_variable(sd, bptr->outvars[i]);
4767 : }
4768 : }
4769 : else
4770 : putchar('-');
4771 : printf("]");
4772 :
4773 : if (bptr->original)
4774 : printf(" (clone of L%03d)", bptr->original->nr);
4775 : else {
4776 : basicblock *b = bptr->copied_to;
4777 : if (b) {
4778 : printf(" (copied to ");
4779 : for (; b; b = b->copied_to)
4780 : printf("L%03d ", b->nr);
4781 : printf(")");
4782 : }
4783 : }
4784 : }
4785 :
4786 :
4787 : static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4788 : {
4789 : int i;
4790 :
4791 : printf("======================================== STACK %sANALYSE BLOCK ",
4792 : (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4793 : stack_verbose_show_block(sd, sd->bptr);
4794 : printf("\n");
4795 :
4796 : if (sd->handlers[0]) {
4797 : printf("HANDLERS: ");
4798 : for (i=0; sd->handlers[i]; ++i) {
4799 : printf("L%03d ", sd->handlers[i]->handler->nr);
4800 : }
4801 : printf("\n");
4802 : }
4803 : printf("\n");
4804 : }
4805 :
4806 :
4807 : static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4808 : {
4809 : printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4810 : stack_verbose_show_block(sd, sd->bptr);
4811 : printf("\n");
4812 : }
4813 :
4814 : static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackelement_t *curstack)
4815 : {
4816 : stackelement_t *sp;
4817 : s4 i;
4818 : s4 depth;
4819 : varinfo *v;
4820 : stackelement_t **stack;
4821 :
4822 : printf(" javalocals ");
4823 : show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4824 : printf(" stack [");
4825 :
4826 : for(i = 0, sp = curstack; sp; sp = sp->prev)
4827 : i++;
4828 : depth = i;
4829 :
4830 : stack = MNEW(stackelement_t *, depth);
4831 : for(sp = curstack; sp; sp = sp->prev)
4832 : stack[--i] = sp;
4833 :
4834 : for(i=0; i<depth; ++i) {
4835 : if (i)
4836 : putchar(' ');
4837 : sp = stack[i];
4838 : v = &(sd->var[sp->varnum]);
4839 :
4840 : if (v->flags & INOUT)
4841 : putchar('I');
4842 : if (v->flags & PREALLOC)
4843 : putchar('A');
4844 : printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4845 : if (v->type == TYPE_RET) {
4846 : printf("(L%03d)", v->vv.retaddr->nr);
4847 : }
4848 : }
4849 : printf("] ... ");
4850 : if (iptr)
4851 : show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4852 : printf("\n");
4853 : }
4854 : #endif
4855 :
4856 :
4857 : /*
4858 : * These are local overrides for various environment variables in Emacs.
4859 : * Please do not remove this and leave it at the end of the file, where
4860 : * Emacs will automagically detect them.
4861 : * ---------------------------------------------------------------------
4862 : * Local variables:
4863 : * mode: c++
4864 : * indent-tabs-mode: t
4865 : * c-basic-offset: 4
4866 : * tab-width: 4
4867 : * End:
4868 : * vim:noexpandtab:sw=4:ts=4:
4869 : */
|