* configure.ac: Define ENABLE_TLH if ENABLE_SSA
[cacao.git] / src / vm / jit / optimizing / bytecode_escape.c
1 /* src/vm/optimizing/bytecode_escape.c
2
3    Copyright (C) 2008
4    CACAOVM - Verein zu Foerderung der freien virtuellen Machine 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 #include "mm/dumpmemory.h"
25 #include "mm/memory.h"
26
27 #include "toolbox/bitvector.h"
28
29 #include "vm/global.h"
30 #include "vm/jit/ir/bytecode.h"
31 #include "vm/jit/optimizing/escape.h"
32 #include "vm/resolve.h"
33
34 #include "vmcore/class.h"
35 #include "vmcore/descriptor.h"
36 #include "vmcore/references.h"
37
38 #include <assert.h>
39 #include <stdarg.h>
40
41 #define BC_ESCAPE_VERBOSE !defined(NDEBUG)
42
43 /*** dprintf *****************************************************************/
44
45 #if BC_ESCAPE_VERBOSE && 0
46 void dprintf(int depth, const char *fmt, ...) {
47         va_list ap;
48
49         while (depth-- > 0) {
50                 printf("    ");
51         }
52         printf("| ");
53
54         va_start(ap, fmt);
55         vprintf(fmt, ap);
56         va_end(ap);
57 }
58 #endif
59
60 #define dprintf(x, ...) printf(__VA_ARGS__)
61
62 /*** op_stack_slot  **********************************************************/
63
64 typedef enum {
65         OP_STACK_SLOT_TYPE_PARAM = 0,
66         OP_STACK_SLOT_TYPE_UNKNOWN = 1
67 } op_stack_slot_type_t;
68
69 typedef struct {
70         unsigned type:1;
71         unsigned index:31;
72 } op_stack_slot_t;
73
74 const op_stack_slot_t OP_STACK_SLOT_UNKNOWN = { 
75         OP_STACK_SLOT_TYPE_UNKNOWN,
76         0
77 };
78
79 static inline op_stack_slot_t op_stack_slot_create_param(s4 index) {
80         op_stack_slot_t res;
81         res.type = OP_STACK_SLOT_TYPE_PARAM;
82         res.index = index;
83         return res;
84 }
85
86 static inline bool op_stack_slot_is_unknown(const op_stack_slot_t slot) {
87         return slot.type == OP_STACK_SLOT_TYPE_UNKNOWN;
88 }
89
90 static inline bool op_stack_slot_is_param(const op_stack_slot_t slot) {
91         return slot.type == OP_STACK_SLOT_TYPE_PARAM;
92 }
93
94 /*** op_stack *****************************************************************/
95
96 /*
97
98 +---+---+---+---+  push 1
99         ^
100
101 +---+---+-1-+---+  push 2
102             ^
103
104 +---+---+-1-+-2-+  pop 2
105                 ^
106
107 +---+---+-1-+---+  pop 1
108             ^        
109
110 +---+---+---+---+  
111         ^
112 */
113
114 typedef struct {
115         op_stack_slot_t *elements;
116         op_stack_slot_t *start;
117         op_stack_slot_t *end;
118         op_stack_slot_t *ptr;
119         op_stack_slot_t *bottom;
120         unsigned max;
121         bool *perror_flag;
122 } op_stack_t;
123
124 static void op_stack_init(op_stack_t *stack, unsigned max, bool *perror_flag) {
125         op_stack_slot_t *it;
126
127         stack->elements = DMNEW(op_stack_slot_t, max * 2);
128         stack->max = max;
129         stack->start = stack->elements + max;
130         stack->end = stack->elements + max + max;
131
132         for (it = stack->elements; it != stack->start; ++it) {
133                 *it = OP_STACK_SLOT_UNKNOWN;
134         }
135
136         stack->ptr = stack->start;
137         stack->bottom = stack->start;
138
139         stack->perror_flag = perror_flag;
140 }
141
142 static void op_stack_set_error(op_stack_t *stack) {
143         *(stack->perror_flag) = true;
144 #if BC_ESCAPE_VERBOSE
145         printf("%s: error.\n", __FUNCTION__);
146 #endif
147 }
148
149 static bool op_stack_test_position(op_stack_t *stack, op_stack_slot_t *pos) {
150         if (!(stack->elements <= pos)) {
151                 op_stack_set_error(stack);
152                 return false;
153         } else if (!(pos < stack->end)) {
154                 op_stack_set_error(stack);
155                 return false;
156         } else {
157                 return true;
158         }
159 }
160
161 static void op_stack_reset(op_stack_t *stack) {
162         op_stack_slot_t *it;
163
164         /* Clear bottom half. */
165
166         for (it = stack->bottom; it != stack->elements + stack->max; ++it) {
167                 *it = OP_STACK_SLOT_UNKNOWN;
168         }
169
170         /* Reset pointers. */
171
172         stack->ptr = stack->start;
173         stack->bottom = stack->start;
174 }
175
176 static op_stack_slot_t op_stack_pop(op_stack_t *stack) {
177         op_stack_slot_t ret;
178         stack->ptr -= 1;
179         if (! op_stack_test_position(stack, stack->ptr)) {
180                 return OP_STACK_SLOT_UNKNOWN;
181         }
182         ret = *(stack->ptr);
183         if (stack->ptr < stack->bottom) {
184                 stack->bottom = stack->ptr;
185         }
186         return ret;
187 }
188
189 static void op_stack_push(op_stack_t *stack, op_stack_slot_t element) {
190         if (op_stack_test_position(stack, stack->ptr)) {
191                 *(stack->ptr) = element;
192                 stack->ptr += 1;
193         }
194 }
195
196 static op_stack_slot_t op_stack_get(const op_stack_t *stack, int offset) {
197         if (op_stack_test_position(stack, stack->ptr - offset)) {
198                 return *(stack->ptr - offset);
199         } else {
200                 return OP_STACK_SLOT_UNKNOWN;
201         }
202 }
203
204 static void op_stack_set(op_stack_t *stack, int offset, op_stack_slot_t value) {
205         if (op_stack_test_position(stack, stack->ptr - offset)) {
206                 *(stack->ptr - offset) = value;
207         }
208 }
209
210 static inline void op_stack_push_unknown(op_stack_t *stack) {
211         op_stack_push(stack, OP_STACK_SLOT_UNKNOWN);
212 }
213
214 static void op_stack_print(const op_stack_t *stack, FILE *f) {
215         op_stack_slot_t *it;
216         char sep;
217         
218         for (it = stack->bottom; it < stack->ptr; ++it) {
219                 if (it == stack->start) {
220                         sep = '!';
221                 } else {
222                         sep = '|';
223                 }
224                 if (op_stack_slot_is_unknown(*it)) {
225                         fprintf(f, "%c----", sep);
226                 } else {
227                         fprintf(f, "%cP%3d", sep, it->index);
228                 }
229         }
230
231         fprintf(f, "|");
232 }
233
234 static bool op_stack_is_empty(const op_stack_t *stack) {
235         return !(stack->bottom < stack->ptr);
236 }
237
238 static s4 op_stack_element_count(const op_stack_t *stack) {
239         return (stack->ptr - stack->bottom);
240 }
241
242 /*** bit_vector **************************************************************/
243
244 typedef struct {
245         bitvector bv;
246         s4 size;
247 } bit_vector_t;
248
249 static void bit_vector_init(bit_vector_t *bv, s4 size) {
250         bv->bv = bv_new(size);
251         bv->size = size;
252 }
253
254 static s4 bit_vector_size(const bit_vector_t *bv) {
255         return bv->size;
256 }
257
258 static void bit_vector_set(bit_vector_t *bv, s4 bit) {
259         assert(0 <= bit && bit < bv->size);
260         bv_set_bit(bv->bv, bit);
261 }
262
263 static bool bit_vector_get(const bit_vector_t *bv, s4 bit) {
264         assert(0 <= bit && bit < bv->size);
265         return bv_get_bit(bv->bv, bit);
266 }
267
268 /*** basicblock_work_list ***********************************************/
269
270 typedef struct basicblock_work_item {
271         s4 bytecode_index;
272         struct basicblock_work_item *next;
273 } basicblock_work_item_t;
274
275 typedef struct {
276         basicblock_work_item_t *first;
277         basicblock_work_item_t *last;
278 } basicblock_work_list_t;
279
280 void basicblock_work_list_init(basicblock_work_list_t *lst) {
281         lst->first = NULL;
282         lst->last = NULL;
283 }
284
285 #define FOR_EACH_BASICBLOCK_WORK_LIST(lst, it) \
286         for ((it) = (lst)->first; (it); (it) = (it)->next)
287
288 void basicblock_work_list_insert(basicblock_work_list_t *lst, s4 bytecode_index) {
289         basicblock_work_item_t *it, *item;
290
291         /* If the destination is already present in the list, do nothing. */
292
293         FOR_EACH_BASICBLOCK_WORK_LIST(lst, it) {
294                 if (it->bytecode_index == bytecode_index) {
295                         return;
296                 }
297         }
298
299         item = DNEW(basicblock_work_item_t);
300         item->bytecode_index = bytecode_index;
301         item->next = NULL;
302
303         if (lst->first == NULL) {
304                 lst->first = item;
305                 lst->last = item;
306         } else {
307                 lst->last->next = item;
308                 lst->last = item;
309         }
310 }
311
312 /*** value_category *****************************************************/
313
314 typedef enum {
315         VALUE_CATEGORY_1,
316         VALUE_CATEGORY_2
317 } value_category_t;
318
319 /*** jcode **************************************************************/
320
321 typedef struct {
322         u1 *start;
323         u1 *end;
324         u1 *pos;
325         u1 *instruction_start;
326         s4 offset;
327         bool *perror_flag;
328 } jcode_t;
329
330 static void jcode_init(jcode_t *jc, u1 *start, s4 length, s4 offset, bool *perror_flag) {
331         jc->start = start;
332         jc->end = jc->start + length;
333         jc->pos = jc->start;
334         jc->offset = offset;
335         jc->perror_flag = perror_flag;
336 }
337
338 static void jcode_set_error(jcode_t *jc) {
339         *(jc->perror_flag) = true;
340 #if BC_ESCAPE_VERBOSE
341         printf("%s: error.\n", __FUNCTION__);
342 #endif
343 }
344
345 static void jcode_move_to_index(jcode_t *jc, s4 index) {
346         jc->pos = jc->start + (index - jc->offset);
347 }
348
349 static bool jcode_end(const jcode_t *jc) {
350         return (jc->pos >= jc->end);
351 }
352
353 static void jcode_record_instruction_start(jcode_t *jc) {
354         jc->instruction_start = jc->pos;
355 }
356
357 static void jcode_rewind_instruction(jcode_t *jc) {
358         jc->pos = jc->instruction_start;
359 }
360
361 static s4 jcode_get_instruction_length(const jcode_t *jc) {
362         return (jc->pos - jc->instruction_start);
363 }
364
365 static void jcode_align_bytecode_index(jcode_t *jc, s4 align) {
366         s4 idx, aidx;
367
368         idx = jc->offset + (jc->pos - jc->start);
369         aidx = MEMORY_ALIGN(idx, align);
370
371         jc->pos += (aidx - idx);
372 }
373
374 static void jcode_forward_instruction_relative(jcode_t *jc, s4 n) {
375         jc->pos = jc->instruction_start + n;
376 }
377
378 static s4 jcode_get_index(const jcode_t *jc) {
379         return jc->offset + (jc->pos - jc->start);
380 }
381
382 bool jcode_test_has_bytes(jcode_t *jc, s4 n) {
383         if ((jc->pos + n) <= jc->end) {
384                 return true;
385         } else {
386                 jcode_set_error(jc);
387                 return false;
388         }
389 }
390
391 static u1 jcode_get_u1(jcode_t *jc) {
392         u1 ret;
393         if (jcode_test_has_bytes(jc, 1)) {
394                 ret = jc->pos[0];
395                 jc->pos += 1;
396         } else {
397                 ret = 0;
398         }
399         return ret;
400 }
401
402 static s2 jcode_get_s2(jcode_t *jc) {
403         s2 ret;
404         if (jcode_test_has_bytes(jc, 2)) {
405                 ret = (jc->pos[0] << 8) | (jc->pos[1]);
406                 jc->pos += 2;
407         } else {
408                 ret = 0;
409         }
410         return ret;
411 }
412
413 static u2 jcode_get_u2(jcode_t *jc) {
414         u2 ret;
415         if (jcode_test_has_bytes(jc, 2)) {
416                 ret = (jc->pos[0] << 8) | (jc->pos[1]);
417                 jc->pos += 2;
418         } else {
419                 ret = 0;
420         }
421         return ret;
422 }
423
424 static s4 jcode_get_s4(jcode_t *jc) {
425         s4 ret;
426         if (jcode_test_has_bytes(jc, 4)) {
427                 ret = (jc->pos[0] << 24) | (jc->pos[1] << 16) | (jc->pos[2] << 8) | (jc->pos[3]);
428                 jc->pos += 4;
429         } else {
430                 ret = 0;
431         }
432         return ret;
433 }
434
435 static s4 jcode_get_branch_target(jcode_t *jc) {
436         s2 off = jcode_get_s2(jc);
437         return jc->offset + (jc->instruction_start - jc->start) + off;
438 }
439
440 static s4 jcode_get_branch_target_wide(jcode_t *jc) {
441         s4 off = jcode_get_s4(jc);
442         return jc->offset + (jc->instruction_start - jc->start) + off;
443 }
444
445 static s4 jcode_get_fall_through_target(jcode_t *jc) {
446         int length = bytecode[*jc->instruction_start].length;
447         if (length <= 0) {
448                 jcode_set_error(jc);
449         }
450         return jc->offset + (jc->instruction_start - jc->start) + length;
451 }
452
453 /*** bc_escape_analysis *************************************************/
454
455 typedef struct {
456         methodinfo *method;
457         op_stack_t *stack;
458         basicblock_work_list_t *basicblocks;
459
460         op_stack_slot_t *local_to_adr_param;
461         s4 local_to_adr_param_size;
462
463         u1 *param_escape;
464         s4 param_escape_size;
465
466         bit_vector_t *adr_param_dirty;
467         bit_vector_t *adr_param_returned;
468
469         s4 non_escaping_adr_params;
470
471 #if BC_ESCAPE_VERBOSE
472         bool verbose;
473 #endif
474         int depth;
475
476         bool fatal_error;
477 } bc_escape_analysis_t;
478
479 static void bc_escape_analysis_perform_intern(methodinfo *m, int depth);
480
481 static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, bool verbose, int depth) {
482         u2 p;
483         int l;
484         int a;
485         u1 *ite;
486         u1 t;
487         unsigned n;
488         int ret_val_is_adr;
489
490         be->method = m;
491
492         be->stack = DNEW(op_stack_t);
493         op_stack_init(be->stack, m->maxstack, &(be->fatal_error));
494
495         be->basicblocks = DNEW(basicblock_work_list_t);
496         basicblock_work_list_init(be->basicblocks);
497
498         be->local_to_adr_param_size = m->parseddesc->paramslots;
499         be->local_to_adr_param = DMNEW(op_stack_slot_t, m->parseddesc->paramslots);
500
501         /* Count number of address parameters a. */
502
503         for (p = 0, l = 0, a = 0; p < m->parseddesc->paramcount; ++p) {
504                 t = m->parseddesc->paramtypes[p].type;
505                 if (t == TYPE_ADR) {
506                         be->local_to_adr_param[l] = op_stack_slot_create_param(a);
507                         a += 1;
508                         l += 1;
509                 } else if (IS_2_WORD_TYPE(t)) {
510                         be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN;
511                         be->local_to_adr_param[l + 1] = OP_STACK_SLOT_UNKNOWN;
512                         l += 2;
513                 } else {
514                         be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN;
515                         l += 1;
516                 }
517         }
518
519         assert(l == be->local_to_adr_param_size);
520
521         ret_val_is_adr = m->parseddesc->returntype.type == TYPE_ADR ? 1 : 0;
522
523         /* Allocate param_escape on heap. */
524
525         be->param_escape_size = a;
526         n = a + ret_val_is_adr;
527
528         if (n == 0) {
529                 /* Use some non-NULL value. */
530                 be->param_escape = (u1 *)1;
531         } else {
532                 be->param_escape = MNEW(u1, n);
533                 be->param_escape += ret_val_is_adr;
534         }
535
536         for (ite = be->param_escape; ite != be->param_escape + n; ++ite) {
537                 *ite = escape_state_to_u1(ESCAPE_NONE);
538         }
539
540         if (ret_val_is_adr) {
541                 be->param_escape[-1] = escape_state_to_u1(ESCAPE_NONE);
542         }
543
544         be->adr_param_dirty = DNEW(bit_vector_t);
545         bit_vector_init(be->adr_param_dirty, a);
546
547         be->adr_param_returned= DNEW(bit_vector_t);
548         bit_vector_init(be->adr_param_returned, a);
549
550         be->non_escaping_adr_params = be->param_escape_size;
551
552 #if BC_ESCAPE_VERBOSE
553         be->verbose = verbose;
554 #endif
555
556         be->depth = depth;
557
558         be->fatal_error = false;
559 }
560
561 static void bc_escape_analysis_branch_target(bc_escape_analysis_t *be, s4 branch_target) {
562         basicblock_work_list_insert(be->basicblocks, branch_target);
563 }
564
565 static void bc_escape_analysis_adjust_state(
566         bc_escape_analysis_t *be, 
567         op_stack_slot_t adr_param,
568         escape_state_t escape_state
569 ) {
570         escape_state_t old;
571
572         if (op_stack_slot_is_param(adr_param)) {
573                 if (0 <= adr_param.index && adr_param.index < be->param_escape_size) {
574                         old = (escape_state_t)be->param_escape[adr_param.index];
575                         if (old < escape_state) {
576
577                                 /* Adjust escape state. */
578                                 be->param_escape[adr_param.index] = (u1)escape_state;
579
580                                 /* If the parameter has just escaped, decrement number of non-escaping
581                                    parameters. */
582
583                                 if (
584                                         old < ESCAPE_GLOBAL && 
585                                         escape_state >= ESCAPE_GLOBAL
586                                 ) {
587                                         be->non_escaping_adr_params -= 1;
588                                 }
589                         }
590                 }
591         }
592 }
593
594 static void bc_escape_analysis_dirty(bc_escape_analysis_t *be, s4 local) {
595         op_stack_slot_t adr_param;
596
597         if (0 <= local && local < be->local_to_adr_param_size) {
598                 adr_param = be->local_to_adr_param[local];
599                 if (op_stack_slot_is_param(adr_param)) {
600                         bit_vector_set(be->adr_param_dirty, adr_param.index);
601                 }
602         }
603 }
604
605 static void bc_escape_analysis_dirty_2(bc_escape_analysis_t *be, s4 local) {
606         bc_escape_analysis_dirty(be, local);
607         bc_escape_analysis_dirty(be, local + 1);
608 }
609
610 static void bc_escape_analysis_returned(bc_escape_analysis_t *be, op_stack_slot_t value) {
611         if (op_stack_slot_is_param(value)) {
612                 /* A parameter is returned, mark it as being returned. */
613                 bit_vector_set(be->adr_param_returned, value.index);
614                 /* The escape state of the return value will be adjusted later. */
615         } else {
616                 /* Adjust escape state of return value. */
617                 if (be->method->parseddesc->returntype.type == TYPE_ADR) {
618                         be->param_escape[-1] = escape_state_to_u1(ESCAPE_GLOBAL);
619                 }
620                 bc_escape_analysis_adjust_state(be, value, ESCAPE_GLOBAL);
621         }
622 }
623
624 op_stack_slot_t bc_escape_analysis_address_local(bc_escape_analysis_t *be, s4 local) {
625         if (0 <= local && local < be->local_to_adr_param_size) {
626                 return be->local_to_adr_param[local];
627         } else {
628                 return OP_STACK_SLOT_UNKNOWN;
629         }
630 }
631
632 value_category_t bc_escape_analysis_value_category(bc_escape_analysis_t *be, s4 index) {
633         constant_FMIref *fmi;
634         fmi = class_getconstant(be->method->clazz, index, CONSTANT_Fieldref);
635
636         if (fmi == NULL) {
637                 /* TODO */
638                 assert(0);
639         }
640
641         switch (fmi->parseddesc.fd->type) {
642                 case TYPE_LNG:
643                 case TYPE_DBL:
644                         return VALUE_CATEGORY_2;
645                 default:
646                         return VALUE_CATEGORY_1;
647         }
648 }
649
650 static void bc_escape_analysis_push_return_value(
651         bc_escape_analysis_t *be,
652         methoddesc *md
653 ) {
654         switch (md->returntype.type) {
655                 case TYPE_LNG:
656                 case TYPE_DBL:
657                         op_stack_push_unknown(be->stack);
658                         op_stack_push_unknown(be->stack);
659                         break;
660                 case TYPE_VOID:
661                         /* Do nothing */
662                         break;
663                 default:
664                         op_stack_push_unknown(be->stack);
665                         break;
666         }
667 }
668
669 static void bc_escape_analysis_adjust_invoke_parameters(
670         bc_escape_analysis_t *be,
671         methodinfo *mi
672 ) {
673         int i;
674         methoddesc *md = mi->parseddesc;
675         u1 *paramescape = mi->paramescape;
676         s4 stack_depth = md->paramslots;
677         unsigned num_params_returned = 0;
678         op_stack_slot_t param_returned;
679
680         /* Process parameters. 
681          * The first parameter is at the highest depth on the stack.
682          */
683
684         for (i = 0; i < md->paramcount; ++i) {
685                 switch (md->paramtypes[i].type) {
686                         case TYPE_ADR:
687                                 if (*paramescape & 0x80) {
688                                         num_params_returned += 1;
689                                         param_returned = op_stack_get(be->stack, stack_depth);
690                                 }
691                                 bc_escape_analysis_adjust_state(
692                                         be,
693                                         op_stack_get(be->stack, stack_depth),
694                                         escape_state_from_u1(*paramescape++)
695                                 );
696                                 stack_depth -= 1;
697                                 break;
698                         case TYPE_LNG:
699                         case TYPE_DBL:
700                                 stack_depth -= 2;
701                                 break;
702                         default:
703                                 stack_depth -= 1;
704                                 break;
705                 }
706         }
707
708         /* Pop all parameters. */
709
710         for (i = 0; i < md->paramslots; ++i) {
711                 op_stack_pop(be->stack);
712         }
713         
714         /* Push return value. */
715
716         if (md->returntype.type == TYPE_ADR) {
717                 if ((num_params_returned == 1) && (mi->paramescape[-1] < ESCAPE_GLOBAL)) {
718                         /* Only a single argument can be returned by the method,
719                            and the retun value does not escape otherwise. */
720                         op_stack_push(be->stack, param_returned);
721                 } else {
722                         op_stack_push_unknown(be->stack);
723                 }
724         } else {
725                 bc_escape_analysis_push_return_value(be, md);
726         }
727 }
728
729 static void bc_escape_analysis_escape_invoke_parameters(
730         bc_escape_analysis_t *be,
731         methoddesc *md
732 ) {
733         s4 i;
734         for (i = 0; i < md->paramslots; ++i) {
735                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
736         }
737
738         bc_escape_analysis_push_return_value(be, md);
739 }
740
741 static void bc_escape_analysis_parse_invoke(bc_escape_analysis_t *be, jcode_t *jc) {
742         constant_FMIref *fmi;
743         methoddesc *md;
744         u1 opc;
745         u2 cp_index;
746         s2 i;
747         resolve_result_t result;
748         methodinfo *mi;
749
750         opc = jcode_get_u1(jc);
751         cp_index = jcode_get_u2(jc);
752
753         /* Get method reference */
754
755         if (opc == BC_invokeinterface) {
756                 fmi = class_getconstant(be->method->clazz, cp_index, CONSTANT_InterfaceMethodref);
757         } else {
758                 fmi = class_getconstant(be->method->clazz, cp_index, CONSTANT_Methodref);
759         }
760
761         if (fmi == NULL) {
762                 /* TODO */
763                 assert(0);
764         }
765
766         md = fmi->parseddesc.md;
767
768         assert(md != NULL);
769
770         /* Parse parameters if not done yet. */
771
772         if (md->params == NULL) {
773                 if (! descriptor_params_from_paramtypes(md, opc == BC_invokestatic ? ACC_STATIC : 0)) {
774                         /* TODO */
775                         assert(0);
776                 }
777         }
778
779         /* Try to lazyly resolve method. */
780
781         result = resolve_method_lazy(be->method, fmi, opc == BC_invokespecial);
782
783         if (result == resolveSucceeded) {
784                 mi = fmi->p.method;
785
786 #if BC_ESCAPE_VERBOSE
787                 if (be->verbose) {
788                         dprintf(
789                                 be->depth,
790                                 "Succefully resolved callee %s/%s. Recursing.\n",
791                                 mi->clazz->name->text,
792                                 mi->name->text
793                         );
794                 }
795 #endif
796         } else {
797                 mi = NULL;
798 #if BC_ESCAPE_VERBOSE
799                 if (be->verbose) {
800                         dprintf(
801                                 be->depth,
802                                 "Failed to resolve callee %s/%s.\n", 
803                                 (IS_FMIREF_RESOLVED(fmi) ? "ERR" : fmi->p.classref->name->text),
804                                 fmi->name->text
805                         );
806                 }
807 #endif
808         }
809
810         /* If we could resolve the method, either reuse available escape inormation
811            or recurse into callee. 
812            Otherwise we must assume, that all parameters escape. */
813
814         if (mi != NULL && method_profile_is_monomorphic(mi)) {
815
816                 if (mi->paramescape == NULL) {
817                         bc_escape_analysis_perform_intern(mi, be->depth + 1);
818                 }
819
820                 if (mi->paramescape == NULL) {
821                         /* No escape information. */
822                         bc_escape_analysis_escape_invoke_parameters(be, md);
823                 } else {
824                         /* Adjust escape state of parameters. */
825                         bc_escape_analysis_adjust_invoke_parameters(be, mi);
826                 }
827
828         } else {
829                 bc_escape_analysis_escape_invoke_parameters(be, md);
830         }
831 }
832
833 static void bc_escape_analysis_parse_tableswitch(
834         bc_escape_analysis_t *be, 
835         jcode_t *jc
836 ) {
837         s4 high, low, def;
838         s4 i;
839
840         jcode_get_u1(jc); /* opcode */
841
842         jcode_align_bytecode_index(jc, 4);
843
844         def = jcode_get_s4(jc);
845         low = jcode_get_s4(jc);
846         high = jcode_get_s4(jc);
847
848         if (low <= high) {
849                 for (i = 0; i < (high - low + 1); ++i) {
850                         bc_escape_analysis_branch_target(
851                                 be,
852                                 jcode_get_branch_target_wide(jc)
853                         );
854                 }
855         }
856
857 }
858
859 static void bc_escape_analysis_parse_lookupswitch(
860         bc_escape_analysis_t *be, 
861         jcode_t *jc
862 ) {
863         s4 npairs;
864         s4 i;
865
866         jcode_get_u1(jc); /* opcode */
867
868         jcode_align_bytecode_index(jc, 4);
869
870         /* default */
871
872         bc_escape_analysis_branch_target(
873                 be,
874                 jcode_get_branch_target_wide(jc)
875         );
876
877         /* npairs */
878
879         npairs = jcode_get_s4(jc);
880
881         for (i = 0; i < npairs; ++i) {
882                 /* Match */
883                 jcode_get_s4(jc);
884
885                 /* Offset */
886                 bc_escape_analysis_branch_target(
887                         be,
888                         jcode_get_branch_target_wide(jc)
889                 );
890         }
891
892 }
893
894 static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcode_t *jc) {
895         u1 opc;
896         op_stack_slot_t value1, value2, value3, value4;
897         u1 dim;
898         int length;
899         bool bb_end = false;
900
901 #if BC_ESCAPE_VERBOSE
902         if (be->verbose) {
903                 dprintf(be->depth, "Processing basicblock at offset %d.\n", jcode_get_index(jc));
904         }
905 #endif
906
907         op_stack_reset(be->stack);
908
909         /* TODO end if all parameters escape */
910         /* TODO move code into process_instruction or the like */
911
912         while ((! jcode_end(jc)) && (! bb_end) && (! be->fatal_error)) {
913
914                 jcode_record_instruction_start(jc);
915
916                 opc = jcode_get_u1(jc);
917
918                 length = bytecode[opc].length;
919
920 #if BC_ESCAPE_VERBOSE   
921                 if (be->verbose) {
922                         dprintf(be->depth, "* %s, ", bytecode[opc].mnemonic);
923                         op_stack_print(be->stack, stdout);
924                         printf(" => ");
925                 }
926 #endif
927
928                 switch (opc) {
929                         case BC_nop:
930                                 break;
931
932                         case BC_aconst_null:
933                         case BC_iconst_m1:
934                         case BC_iconst_0:
935                         case BC_iconst_1:
936                         case BC_iconst_2:
937                         case BC_iconst_3:
938                         case BC_iconst_4:
939                         case BC_iconst_5:
940                         case BC_fconst_0:
941                         case BC_fconst_1:
942                         case BC_fconst_2:
943                                 op_stack_push_unknown(be->stack);
944                                 break;
945
946                         case BC_dconst_0:
947                         case BC_dconst_1:
948                         case BC_lconst_0:
949                         case BC_lconst_1:
950                                 op_stack_push_unknown(be->stack);
951                                 op_stack_push_unknown(be->stack);
952                                 break;
953
954                         case BC_bipush:
955                         case BC_sipush:
956                                 op_stack_push_unknown(be->stack);
957                                 break;
958
959                         case BC_ldc1:
960                         case BC_ldc2:
961                                 op_stack_push_unknown(be->stack);
962                                 break;
963
964                         case BC_ldc2w:
965                                 op_stack_push_unknown(be->stack);
966                                 op_stack_push_unknown(be->stack);
967                                 break;
968
969                         case BC_iload:
970                         case BC_fload:
971                         case BC_iload_0:
972                         case BC_iload_1:
973                         case BC_iload_2:
974                         case BC_iload_3:
975                         case BC_fload_0:
976                         case BC_fload_1:
977                         case BC_fload_2:
978                         case BC_fload_3:
979                                 op_stack_push_unknown(be->stack);
980                                 break;
981
982                         case BC_dload:
983                         case BC_lload:
984                         case BC_lload_0:
985                         case BC_lload_1:
986                         case BC_lload_2:
987                         case BC_lload_3:
988                         case BC_dload_0:
989                         case BC_dload_1:
990                         case BC_dload_2:
991                         case BC_dload_3:
992                                 op_stack_push_unknown(be->stack);
993                                 op_stack_push_unknown(be->stack);
994                                 break;
995
996                         case BC_aload:
997                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, jcode_get_u1(jc)));
998                                 break;
999
1000                         case BC_aload_0:
1001                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 0));
1002                                 break;
1003
1004                         case BC_aload_1:
1005                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 1));
1006                                 break;
1007
1008                         case BC_aload_2:
1009                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 2));
1010                                 break;
1011
1012                         case BC_aload_3:
1013                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 3));
1014                                 break;
1015
1016                         case BC_iaload:
1017                         case BC_faload:
1018                         case BC_baload:
1019                         case BC_caload:
1020                         case BC_saload:
1021                                 op_stack_pop(be->stack);
1022                                 op_stack_pop(be->stack);
1023                                 op_stack_push_unknown(be->stack);
1024                                 break;
1025
1026                         case BC_laload:
1027                         case BC_daload:
1028                                 op_stack_pop(be->stack);
1029                                 op_stack_pop(be->stack);
1030                                 op_stack_push_unknown(be->stack);
1031                                 op_stack_push_unknown(be->stack);
1032                                 break;
1033
1034                         case BC_aaload:
1035                                 op_stack_pop(be->stack);
1036                                 op_stack_pop(be->stack);
1037                                 op_stack_push_unknown(be->stack);
1038                                 break;
1039
1040                         case BC_istore:
1041                         case BC_fstore:
1042                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1043                                 op_stack_pop(be->stack);
1044                                 break;
1045
1046                         case BC_istore_0:
1047                         case BC_fstore_0:
1048                                 bc_escape_analysis_dirty(be, 0);
1049                                 op_stack_pop(be->stack);
1050                                 break;
1051
1052                         case BC_istore_1:
1053                         case BC_fstore_1:
1054                                 bc_escape_analysis_dirty(be, 1);
1055                                 op_stack_pop(be->stack);
1056                                 break;
1057
1058                         case BC_istore_2:
1059                         case BC_fstore_2:
1060                                 bc_escape_analysis_dirty(be, 2);
1061                                 op_stack_pop(be->stack);
1062                                 break;
1063
1064                         case BC_istore_3:
1065                         case BC_fstore_3:
1066                                 bc_escape_analysis_dirty(be, 3);
1067                                 op_stack_pop(be->stack);
1068                                 break;
1069
1070                         case BC_lstore:
1071                         case BC_dstore:
1072                                 bc_escape_analysis_dirty_2(be, jcode_get_u1(jc));
1073                                 op_stack_pop(be->stack);
1074                                 op_stack_pop(be->stack);
1075                                 break;
1076
1077                         case BC_lstore_0:
1078                         case BC_dstore_0:
1079                                 bc_escape_analysis_dirty_2(be, 0);
1080                                 op_stack_pop(be->stack);
1081                                 op_stack_pop(be->stack);
1082                                 break;
1083
1084                         case BC_lstore_1:
1085                         case BC_dstore_1:
1086                                 bc_escape_analysis_dirty_2(be, 1);
1087                                 op_stack_pop(be->stack);
1088                                 op_stack_pop(be->stack);
1089                                 break;
1090
1091                         case BC_lstore_2:
1092                         case BC_dstore_2:
1093                                 bc_escape_analysis_dirty_2(be, 2);
1094                                 op_stack_pop(be->stack);
1095                                 op_stack_pop(be->stack);
1096                                 break;
1097
1098                         case BC_lstore_3:
1099                         case BC_dstore_3:
1100                                 bc_escape_analysis_dirty_2(be, 3);
1101                                 op_stack_pop(be->stack);
1102                                 op_stack_pop(be->stack);
1103                                 break;
1104
1105                         case BC_astore:
1106                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1107                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1108                                 break;
1109
1110                         case BC_astore_0:
1111                                 bc_escape_analysis_dirty(be, 0);
1112                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1113                                 break;
1114
1115                         case BC_astore_1:
1116                                 bc_escape_analysis_dirty(be, 1);
1117                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1118                                 break;
1119
1120                         case BC_astore_2:
1121                                 bc_escape_analysis_dirty(be, 2);
1122                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1123                                 break;
1124
1125                         case BC_astore_3:
1126                                 bc_escape_analysis_dirty(be, 3);
1127                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1128                                 break;
1129
1130                         case BC_iastore:
1131                         case BC_fastore:
1132                         case BC_bastore:
1133                         case BC_castore:
1134                         case BC_sastore:
1135                                 op_stack_pop(be->stack);
1136                                 op_stack_pop(be->stack);
1137                                 op_stack_pop(be->stack);
1138                                 break;
1139
1140                         case BC_lastore:
1141                         case BC_dastore:
1142                                 op_stack_pop(be->stack);
1143                                 op_stack_pop(be->stack);
1144                                 op_stack_pop(be->stack);
1145                                 op_stack_pop(be->stack);
1146                                 break;
1147
1148                         case BC_aastore:
1149                                 op_stack_pop(be->stack);
1150                                 op_stack_pop(be->stack);
1151                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1152                                 break;
1153
1154                         case BC_pop:
1155                                 op_stack_pop(be->stack);
1156                                 break;
1157
1158                         case BC_pop2:
1159                                 op_stack_pop(be->stack);
1160                                 op_stack_pop(be->stack);
1161                                 break;
1162
1163                         case BC_dup:
1164                                 value1 = op_stack_get(be->stack, 1);
1165                                 op_stack_push(be->stack, value1);
1166                                 break;
1167
1168                         case BC_dup_x1:
1169                                 value1 = op_stack_pop(be->stack);
1170                                 value2 = op_stack_pop(be->stack);
1171                                 op_stack_push(be->stack, value1);
1172                                 op_stack_push(be->stack, value2);
1173                                 op_stack_push(be->stack, value1);
1174                                 break;
1175
1176                         case BC_dup_x2:
1177                                 value1 = op_stack_pop(be->stack);
1178                                 value2 = op_stack_pop(be->stack);
1179                                 value3 = op_stack_pop(be->stack);
1180                                 op_stack_push(be->stack, value1);
1181                                 op_stack_push(be->stack, value3);
1182                                 op_stack_push(be->stack, value2);
1183                                 op_stack_push(be->stack, value1);
1184                                 break;
1185                                 
1186                         case BC_dup2:
1187                                 value1 = op_stack_get(be->stack, 1);
1188                                 value2 = op_stack_get(be->stack, 2);
1189                                 op_stack_push(be->stack, value2);
1190                                 op_stack_push(be->stack, value1);
1191                                 break;
1192
1193                         case BC_dup2_x1:
1194                                 value1 = op_stack_pop(be->stack);
1195                                 value2 = op_stack_pop(be->stack);
1196                                 value3 = op_stack_pop(be->stack);
1197                                 op_stack_push(be->stack, value2);
1198                                 op_stack_push(be->stack, value1);
1199                                 op_stack_push(be->stack, value3);
1200                                 op_stack_push(be->stack, value2);
1201                                 op_stack_push(be->stack, value1);
1202                                 break;
1203
1204                         case BC_dup2_x2:
1205                                 value1 = op_stack_pop(be->stack);
1206                                 value2 = op_stack_pop(be->stack);
1207                                 value3 = op_stack_pop(be->stack);
1208                                 value4 = op_stack_pop(be->stack);
1209                                 op_stack_push(be->stack, value2);
1210                                 op_stack_push(be->stack, value1);
1211                                 op_stack_push(be->stack, value4);
1212                                 op_stack_push(be->stack, value3);
1213                                 op_stack_push(be->stack, value2);
1214                                 op_stack_push(be->stack, value1);
1215                                 break;
1216
1217                         case BC_swap:
1218                                 value1 = op_stack_get(be->stack, 1);
1219                                 value2 = op_stack_get(be->stack, 2);
1220                                 op_stack_set(be->stack, 1, value2);
1221                                 op_stack_set(be->stack, 2, value1);
1222                                 break;
1223
1224                         case BC_iadd:
1225                         case BC_fadd:
1226
1227                         case BC_isub:
1228                         case BC_fsub:
1229
1230                         case BC_imul:
1231                         case BC_fmul:
1232
1233                         case BC_idiv:
1234                         case BC_fdiv:
1235
1236                         case BC_irem:
1237                         case BC_frem:
1238
1239                                 op_stack_pop(be->stack);
1240                                 op_stack_pop(be->stack);
1241                                 op_stack_push_unknown(be->stack);
1242                                 break;
1243
1244                         case BC_ladd:
1245                         case BC_dadd:
1246
1247                         case BC_lsub:
1248                         case BC_dsub:
1249
1250                         case BC_ldiv:
1251                         case BC_ddiv:
1252
1253                         case BC_lmul:
1254                         case BC_dmul:
1255
1256                         case BC_lrem:
1257                         case BC_drem:
1258
1259                                 op_stack_pop(be->stack);
1260                                 op_stack_pop(be->stack);
1261                                 op_stack_pop(be->stack);
1262                                 op_stack_pop(be->stack);
1263                                 op_stack_push_unknown(be->stack);
1264                                 op_stack_push_unknown(be->stack);
1265                                 break;
1266
1267                         case BC_ineg:
1268                         case BC_lneg:
1269                         case BC_fneg:
1270                         case BC_dneg:
1271
1272                                 /* Nothing */
1273                                 break;
1274
1275                         case BC_ishl:
1276                         case BC_ishr:
1277                         case BC_iushr:
1278                                 op_stack_pop(be->stack);
1279                                 op_stack_pop(be->stack);
1280                                 op_stack_push_unknown(be->stack);
1281                                 break;
1282
1283                         case BC_lshl:
1284                         case BC_lshr:
1285                         case BC_lushr:
1286                                 op_stack_pop(be->stack);
1287                                 op_stack_pop(be->stack);
1288                                 /* Second operand is int. */
1289                                 op_stack_pop(be->stack);
1290                                 op_stack_push_unknown(be->stack);
1291                                 op_stack_push_unknown(be->stack);
1292                                 break;
1293
1294                         case BC_iand:
1295                         case BC_ior:
1296                         case BC_ixor:
1297                                 op_stack_pop(be->stack);
1298                                 op_stack_pop(be->stack);
1299                                 op_stack_push_unknown(be->stack);
1300                                 break;
1301
1302                         case BC_land:
1303                         case BC_lor:
1304                         case BC_lxor:
1305                                 op_stack_pop(be->stack);
1306                                 op_stack_pop(be->stack);
1307                                 op_stack_pop(be->stack);
1308                                 op_stack_pop(be->stack);
1309                                 op_stack_push_unknown(be->stack);
1310                                 op_stack_push_unknown(be->stack);
1311                                 break;
1312
1313                         case BC_iinc:
1314                                 /* Not stack operation. */
1315                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1316                                 break;
1317
1318                         case BC_i2l:
1319                         case BC_i2d:
1320                                 op_stack_pop(be->stack);
1321                                 op_stack_push_unknown(be->stack);
1322                                 op_stack_push_unknown(be->stack);
1323                                 break;
1324
1325                         case BC_i2f:
1326                                 op_stack_pop(be->stack);
1327                                 op_stack_push_unknown(be->stack);
1328                                 break;
1329
1330                         case BC_l2i:
1331                         case BC_l2f:
1332                                 op_stack_pop(be->stack);
1333                                 op_stack_pop(be->stack);
1334                                 op_stack_push_unknown(be->stack);
1335                                 break;
1336
1337                         case BC_l2d:
1338                                 op_stack_pop(be->stack);
1339                                 op_stack_pop(be->stack);
1340                                 op_stack_push_unknown(be->stack);
1341                                 op_stack_push_unknown(be->stack);
1342                                 break;
1343
1344                         case BC_f2i:
1345                                 op_stack_pop(be->stack);
1346                                 op_stack_push_unknown(be->stack);
1347                                 break;
1348                                 
1349                         case BC_f2l:
1350                         case BC_f2d:
1351                                 op_stack_pop(be->stack);
1352                                 op_stack_push_unknown(be->stack);
1353                                 op_stack_push_unknown(be->stack);
1354                                 break;
1355
1356                         case BC_d2i:
1357                         case BC_d2f:
1358                                 op_stack_pop(be->stack);
1359                                 op_stack_pop(be->stack);
1360                                 op_stack_push_unknown(be->stack);
1361                                 break;
1362
1363                         case BC_d2l:
1364                                 op_stack_pop(be->stack);
1365                                 op_stack_pop(be->stack);
1366                                 op_stack_push_unknown(be->stack);
1367                                 op_stack_push_unknown(be->stack);
1368                                 break;
1369
1370                         case BC_int2byte:
1371                         case BC_int2char:
1372                         case BC_int2short:
1373                                 op_stack_pop(be->stack);
1374                                 op_stack_push_unknown(be->stack);
1375                                 break;
1376
1377                         case BC_fcmpl:
1378                         case BC_fcmpg:
1379                                 op_stack_pop(be->stack);
1380                                 op_stack_pop(be->stack);
1381                                 op_stack_push_unknown(be->stack);
1382                                 break;
1383
1384                         case BC_lcmp:
1385                         case BC_dcmpl:
1386                         case BC_dcmpg:
1387                                 op_stack_pop(be->stack);
1388                                 op_stack_pop(be->stack);
1389                                 op_stack_pop(be->stack);
1390                                 op_stack_pop(be->stack);
1391                                 op_stack_push_unknown(be->stack);
1392                                 break;
1393
1394                         case BC_ifeq:
1395                         case BC_ifne:
1396                         case BC_iflt:
1397                         case BC_ifge:
1398                         case BC_ifgt:
1399                         case BC_ifle:
1400                                 op_stack_pop(be->stack);
1401                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1402                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1403                                 bb_end = true;
1404                                 break;
1405
1406                         case BC_if_icmpeq:
1407                         case BC_if_icmpne:
1408                         case BC_if_icmplt:
1409                         case BC_if_icmpge:
1410                         case BC_if_icmpgt:
1411                         case BC_if_icmple:
1412                                 op_stack_pop(be->stack);
1413                                 op_stack_pop(be->stack);
1414                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1415                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1416                                 bb_end = true;
1417                                 break;
1418
1419                         case BC_if_acmpeq:
1420                         case BC_if_acmpne:
1421                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1422                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1423                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1424                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1425                                 bb_end = true;
1426                                 break;
1427
1428                         case BC_goto:
1429                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1430                                 bb_end = true;
1431                                 break;
1432
1433                         case BC_jsr:
1434                                 op_stack_push_unknown(be->stack);
1435                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1436                                 bb_end = true;
1437                                 break;
1438
1439                         case BC_ret:
1440                                 break;
1441
1442                         case BC_tableswitch:
1443                                 op_stack_pop(be->stack);
1444                                 jcode_rewind_instruction(jc);
1445                                 bc_escape_analysis_parse_tableswitch(be, jc);
1446                                 length = jcode_get_instruction_length(jc);
1447                                 bb_end = 1;
1448                                 break;
1449
1450                         case BC_lookupswitch:
1451                                 op_stack_pop(be->stack);
1452                                 jcode_rewind_instruction(jc);
1453                                 bc_escape_analysis_parse_lookupswitch(be, jc);
1454                                 length = jcode_get_instruction_length(jc);
1455                                 bb_end = 1;
1456                                 break;
1457
1458                         case BC_return:
1459                                 bb_end = true;
1460                                 break;
1461
1462                         case BC_ireturn:
1463                         case BC_freturn:
1464                                 op_stack_pop(be->stack);
1465                                 bb_end = true;
1466                                 break;
1467
1468                         case BC_lreturn:
1469                         case BC_dreturn:
1470                                 op_stack_pop(be->stack);
1471                                 op_stack_pop(be->stack);
1472                                 bb_end = true;
1473                                 break;
1474
1475                         case BC_areturn:
1476                                 /* FIXME */
1477                                 bc_escape_analysis_returned(be, op_stack_pop(be->stack));
1478                                 bb_end = true;
1479                                 break;
1480
1481                         case BC_getfield:
1482                                 op_stack_pop(be->stack);
1483                                 /* Fall through. */
1484
1485                         case BC_getstatic:
1486                                 if (
1487                                         bc_escape_analysis_value_category(be, jcode_get_s2(jc)) == 
1488                                         VALUE_CATEGORY_2
1489                                 ) {
1490                                         op_stack_push_unknown(be->stack);
1491                                 }
1492                                 op_stack_push_unknown(be->stack);
1493                                 break;
1494
1495                         
1496                         case BC_putfield:
1497                                 if (
1498                                         bc_escape_analysis_value_category(be, jcode_get_u2(jc)) == 
1499                                         VALUE_CATEGORY_2
1500                                 ) {
1501                                         op_stack_pop(be->stack);
1502
1503                                         op_stack_pop(be->stack);
1504                                         op_stack_pop(be->stack);
1505                                 } else {
1506                                         value2 = op_stack_pop(be->stack);
1507                                         value1 = op_stack_pop(be->stack);
1508                                         bc_escape_analysis_adjust_state(be, value2, ESCAPE_GLOBAL);
1509                                 }
1510                                 break;
1511
1512                         case BC_putstatic:
1513                                 if (
1514                                         bc_escape_analysis_value_category(be, jcode_get_u2(jc)) == 
1515                                         VALUE_CATEGORY_2
1516                                 ) {
1517                                         op_stack_pop(be->stack);
1518                                         op_stack_pop(be->stack);
1519                                 } else {
1520                                         value1 = op_stack_pop(be->stack);
1521                                         bc_escape_analysis_adjust_state(be, value1, ESCAPE_GLOBAL);
1522                                 }
1523                                 break;
1524
1525                         case BC_invokevirtual:
1526                         case BC_invokespecial:
1527                         case BC_invokestatic:
1528                         case BC_invokeinterface:
1529                                 jcode_rewind_instruction(jc);
1530                                 bc_escape_analysis_parse_invoke(be, jc);
1531                                 break;
1532
1533                         case BC_new:
1534                                 op_stack_push_unknown(be->stack);
1535                                 break;
1536
1537                         case BC_newarray:
1538                         case BC_anewarray:
1539                                 op_stack_pop(be->stack);
1540                                 op_stack_push_unknown(be->stack);
1541                                 break;
1542
1543                         case BC_arraylength:
1544                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1545                                 op_stack_push_unknown(be->stack);
1546                                 break;
1547
1548                         case BC_athrow:
1549                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1550                                 bb_end = true;
1551                                 break;
1552
1553                         case BC_checkcast:
1554                                 value1 = op_stack_get(be->stack, 1);
1555                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1556                                 break;
1557
1558                         case BC_instanceof:
1559                                 value1 = op_stack_pop(be->stack);
1560                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1561                                 op_stack_push_unknown(be->stack);
1562                                 break;
1563
1564                         case BC_monitorenter:
1565                         case BC_monitorexit:
1566                                 value1 = op_stack_pop(be->stack);
1567                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1568                                 break;
1569
1570                         case BC_wide:
1571
1572                                 /* All except iinc have a length of 4. */
1573                                 length = 4;
1574
1575                                 switch (jcode_get_u1(jc)) {
1576                                         case BC_iload:
1577                                         case BC_fload:
1578                                                 op_stack_push_unknown(be->stack);
1579                                                 break;
1580
1581                                         case BC_lload:
1582                                         case BC_dload:
1583                                                 op_stack_push_unknown(be->stack);
1584                                                 op_stack_push_unknown(be->stack);
1585                                                 break;
1586
1587                                         case BC_aload:
1588                                                 op_stack_push(
1589                                                         be->stack, 
1590                                                         bc_escape_analysis_address_local(
1591                                                                 be, 
1592                                                                 jcode_get_u1(jc)
1593                                                         )
1594                                                 );
1595                                                 break;
1596
1597                                         case BC_istore:
1598                                         case BC_fstore:
1599                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1600                                                 op_stack_pop(be->stack);
1601                                                 break;
1602
1603                                         case BC_lstore:
1604                                         case BC_dstore:
1605                                                 bc_escape_analysis_dirty_2(be, jcode_get_u2(jc));
1606                                                 op_stack_pop(be->stack);
1607                                                 op_stack_pop(be->stack);
1608                                                 break;
1609
1610                                         case BC_astore:
1611                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1612                                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1613                                                 break;
1614                                                 
1615                                         case BC_ret:
1616                                                 /* Do nothing. */
1617                                                 break;
1618
1619                                         case BC_iinc:
1620                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1621                                                 length = 6;
1622                                                 /* Do nothing. */
1623                                                 break;
1624                                 }
1625                                 break;
1626
1627                         case BC_multianewarray:
1628                                 jcode_get_u2(jc);
1629                                 dim = jcode_get_u1(jc);
1630                                 while (dim-- > 0) {
1631                                         op_stack_pop(be->stack);
1632                                 }
1633                                 op_stack_push_unknown(be->stack);
1634                                 break;
1635
1636                         case BC_ifnull:
1637                         case BC_ifnonnull:
1638                                 value1 = op_stack_pop(be->stack);
1639                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1640                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1641                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1642                                 bb_end = true;
1643                                 break;
1644
1645                         case BC_goto_w:
1646                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target_wide(jc));
1647                                 bb_end = true;
1648                                 break;
1649
1650                         case BC_jsr_w:
1651                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target_wide(jc));
1652                                 bb_end = true;
1653                                 break;
1654
1655                         case BC_breakpoint:
1656                         case BC_impdep1:
1657                         case BC_impdep2:
1658                                 break;
1659
1660                         default:
1661                                 break;
1662                 }
1663                 assert(length > 0);
1664                 jcode_forward_instruction_relative(jc, length);
1665
1666 #if BC_ESCAPE_VERBOSE
1667                 if (be->verbose) {
1668                         op_stack_print(be->stack, stdout);
1669                         printf("\n");
1670                 }
1671 #endif
1672         }
1673
1674 #if BC_ESCAPE_VERBOSE
1675         if (be->verbose) {
1676                 dprintf(be->depth, "Elements left on stack: %d\n", op_stack_element_count(be->stack));
1677         }
1678 #endif
1679
1680         while ((! op_stack_is_empty(be->stack)) && (! be->fatal_error)) {
1681 #if BC_ESCAPE_VERBOSE
1682                 if (be->verbose) {
1683                         dprintf(be->depth, "Stack element: ");
1684                         op_stack_print(be->stack, stdout);
1685                         printf(" => ");
1686                 }
1687 #endif
1688                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1689 #if BC_ESCAPE_VERBOSE
1690                 if (be->verbose) {
1691                         op_stack_print(be->stack, stdout);
1692                         printf("\n");
1693                 }
1694 #endif
1695         }
1696
1697         if (be->fatal_error) {
1698 #if BC_ESCAPE_VERBOSE
1699                 if (be->verbose) {
1700                         printf("Fatal error while processing basic block. Aborting.\n");
1701                 }
1702 #endif
1703                 assert(0);
1704         }
1705 }
1706
1707 static void     bc_escape_analysis_adjust_return_value(bc_escape_analysis_t *be) {
1708         escape_state_t re, pe;
1709         int i;
1710
1711         /* Only calculate, if return value is of type address. */
1712
1713         if (be->method->parseddesc->returntype.type != TYPE_ADR) {
1714                 return ;
1715         }
1716
1717         /* If a parameter can be returned, adjust to its escape state. */
1718
1719         for (i = 0; i < be->param_escape_size; ++i) {
1720                 if (bit_vector_get(be->adr_param_returned, i)) {
1721                         be->param_escape[i] |= 0x80;
1722
1723                         pe = escape_state_from_u1(be->param_escape[i]);
1724                         re = escape_state_from_u1(be->param_escape[-1]);
1725                         
1726                         if (pe > re) {
1727                                 be->param_escape[-1] = escape_state_to_u1(pe);
1728                         }
1729                 }
1730         }
1731 }
1732
1733 static void bc_escape_analysis_analyze(bc_escape_analysis_t *be) {
1734         raw_exception_entry *itee;
1735         basicblock_work_item_t *bb;
1736         jcode_t jc;
1737
1738         /* Add root as basic block. */
1739
1740         bc_escape_analysis_branch_target(be, 0);
1741
1742         /* Add each exception handler as basic block. */
1743
1744         for (
1745                 itee = be->method->rawexceptiontable;
1746                 itee != be->method->rawexceptiontable + be->method->rawexceptiontablelength;
1747                 ++itee
1748         ) {
1749                 bc_escape_analysis_branch_target(be, itee->handlerpc);
1750         }
1751
1752         /* Init jcode parser. */
1753
1754         jcode_init(
1755                 &jc,
1756                 be->method->jcode,
1757                 be->method->jcodelength,
1758                 0,
1759                 &(be->fatal_error)
1760         );
1761
1762         /* Process basicblock by basicblock. */
1763
1764         for (bb = be->basicblocks->first; bb; bb = bb->next) {
1765                 jcode_move_to_index(&jc, bb->bytecode_index);
1766                 bc_escape_analysis_process_basicblock(
1767                         be,
1768                         &jc
1769                 );
1770         }
1771
1772         /* Calculate escape of return value. */
1773
1774         bc_escape_analysis_adjust_return_value(be);
1775
1776         /* Export escape of parameters. */
1777
1778         be->method->paramescape = be->param_escape;
1779 }
1780
1781 static void bc_escape_analysis_perform_intern(methodinfo *m, int depth) {
1782         bc_escape_analysis_t *be;
1783         bool verbose = false;
1784
1785 #if BC_ESCAPE_VERBOSE
1786         if (verbose) {
1787                 dprintf(
1788                         depth,
1789                         "=== BC escape analysis of %s/%s at depth %d ===\n",
1790                         m->clazz->name->text,
1791                         m->name->text,
1792                         depth
1793                 );
1794         }
1795 #endif
1796
1797         if (m->paramescape != NULL) {
1798 #if BC_ESCAPE_VERBOSE
1799                 if (verbose) {  
1800                         dprintf(depth, "Escape info for method already available.\n");
1801                 }
1802 #endif
1803                 return;
1804         }
1805
1806         if ((m->flags & ACC_METHOD_EA) != 0) {
1807 #if BC_ESCAPE_VERBOSE
1808                 if (verbose) {  
1809                         dprintf(depth, "Detected recursion, aborting.\n");
1810                 }
1811 #endif
1812                 return;
1813         }
1814
1815         if (m->jcode == NULL) {
1816 #if BC_ESCAPE_VERBOSE
1817                 if (verbose) {
1818                         dprintf(depth, "No bytecode for callee.\n");
1819                 }
1820 #endif
1821                 return;
1822         }
1823
1824         /* TODO threshold */
1825
1826         be = DNEW(bc_escape_analysis_t);
1827         bc_escape_analysis_init(be, m, verbose, depth);
1828
1829         m->flags |= ACC_METHOD_EA;
1830
1831         bc_escape_analysis_analyze(be);
1832
1833 #if BC_ESCAPE_VERBOSE
1834         if (be->verbose) {
1835                 dprintf(
1836                         depth,
1837                         "%s/%s: Non-escaping params: %d\n", 
1838                         m->clazz->name->text,
1839                         m->name->text,
1840                         be->non_escaping_adr_params
1841                 );
1842         }
1843 #endif
1844
1845         m->flags &= ~ACC_METHOD_EA;
1846 }
1847
1848 void bc_escape_analysis_perform(methodinfo *m) {
1849         bc_escape_analysis_perform_intern(m, 0);
1850 }
1851
1852