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