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