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