PR163: descriptor_params_from_paramtypes is protected by a mutex now (per descriptor...
[cacao.git] / src / vm / jit / optimizing / bytecode_escape.c
1 /* src/vm/optimizing/bytecode_escape.c
2
3    Copyright (C) 1996-2011
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.hpp"
32
33 #include "toolbox/bitvector.h"
34
35 #include "vm/class.hpp"
36 #include "vm/descriptor.hpp"
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         descriptor_params_from_paramtypes(md, opc == BC_invokestatic ? ACC_STATIC : 0);
779
780         /* Try to lazyly resolve method. */
781
782         result = resolve_method_lazy(be->method, fmi, opc == BC_invokespecial);
783
784         if (result == resolveSucceeded) {
785                 mi = fmi->p.method;
786
787 #if BC_ESCAPE_VERBOSE
788                 if (be->verbose) {
789                         dprintf(
790                                 be->depth,
791                                 "Succefully resolved callee %s/%s. Recursing.\n",
792                                 mi->clazz->name->text,
793                                 mi->name->text
794                         );
795                 }
796 #endif
797         } else {
798                 mi = NULL;
799 #if BC_ESCAPE_VERBOSE
800                 if (be->verbose) {
801                         dprintf(
802                                 be->depth,
803                                 "Failed to resolve callee %s/%s.\n", 
804                                 (IS_FMIREF_RESOLVED(fmi) ? "ERR" : fmi->p.classref->name->text),
805                                 fmi->name->text
806                         );
807                 }
808 #endif
809         }
810
811         /* If we could resolve the method, either reuse available escape inormation
812            or recurse into callee. 
813            Otherwise we must assume, that all parameters escape. */
814
815         if (mi != NULL && escape_is_monomorphic(be->method, mi)) {
816
817                 if (mi->paramescape == NULL) {
818                         bc_escape_analysis_perform_intern(mi, be->depth + 1);
819                 }
820
821                 if (mi->paramescape == NULL) {
822                         /* No escape information. */
823                         bc_escape_analysis_escape_invoke_parameters(be, md);
824                 } else {
825                         /* Adjust escape state of parameters. */
826                         bc_escape_analysis_adjust_invoke_parameters(be, mi);
827                 }
828
829         } else {
830                 bc_escape_analysis_escape_invoke_parameters(be, md);
831         }
832 }
833
834 static void bc_escape_analysis_parse_tableswitch(
835         bc_escape_analysis_t *be, 
836         jcode_t *jc
837 ) {
838         s4 high, low, def;
839         s4 i;
840
841         jcode_get_u1(jc); /* opcode */
842
843         jcode_align_bytecode_index(jc, 4);
844
845         def = jcode_get_s4(jc);
846         low = jcode_get_s4(jc);
847         high = jcode_get_s4(jc);
848
849         if (low <= high) {
850                 for (i = 0; i < (high - low + 1); ++i) {
851                         bc_escape_analysis_branch_target(
852                                 be,
853                                 jcode_get_branch_target_wide(jc)
854                         );
855                 }
856         }
857
858 }
859
860 static void bc_escape_analysis_parse_lookupswitch(
861         bc_escape_analysis_t *be, 
862         jcode_t *jc
863 ) {
864         s4 npairs;
865         s4 i;
866
867         jcode_get_u1(jc); /* opcode */
868
869         jcode_align_bytecode_index(jc, 4);
870
871         /* default */
872
873         bc_escape_analysis_branch_target(
874                 be,
875                 jcode_get_branch_target_wide(jc)
876         );
877
878         /* npairs */
879
880         npairs = jcode_get_s4(jc);
881
882         for (i = 0; i < npairs; ++i) {
883                 /* Match */
884                 jcode_get_s4(jc);
885
886                 /* Offset */
887                 bc_escape_analysis_branch_target(
888                         be,
889                         jcode_get_branch_target_wide(jc)
890                 );
891         }
892
893 }
894
895 static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcode_t *jc) {
896         u1 opc;
897         op_stack_slot_t value1, value2, value3, value4;
898         u1 dim;
899         int length;
900         bool bb_end = false;
901
902 #if BC_ESCAPE_VERBOSE
903         if (be->verbose) {
904                 dprintf(be->depth, "Processing basicblock at offset %d.\n", jcode_get_index(jc));
905         }
906 #endif
907
908         op_stack_reset(be->stack);
909
910         /* TODO end if all parameters escape */
911         /* TODO move code into process_instruction or the like */
912
913         while ((! jcode_end(jc)) && (! bb_end) && (! be->fatal_error)) {
914
915                 jcode_record_instruction_start(jc);
916
917                 opc = jcode_get_u1(jc);
918
919                 length = bytecode[opc].length;
920
921 #if BC_ESCAPE_VERBOSE   
922                 if (be->verbose) {
923                         dprintf(be->depth, "* %s, ", bytecode[opc].mnemonic);
924                         op_stack_print(be->stack, stdout);
925                         printf(" => ");
926                 }
927 #endif
928
929                 switch (opc) {
930                         case BC_nop:
931                                 break;
932
933                         case BC_aconst_null:
934                         case BC_iconst_m1:
935                         case BC_iconst_0:
936                         case BC_iconst_1:
937                         case BC_iconst_2:
938                         case BC_iconst_3:
939                         case BC_iconst_4:
940                         case BC_iconst_5:
941                         case BC_fconst_0:
942                         case BC_fconst_1:
943                         case BC_fconst_2:
944                                 op_stack_push_unknown(be->stack);
945                                 break;
946
947                         case BC_dconst_0:
948                         case BC_dconst_1:
949                         case BC_lconst_0:
950                         case BC_lconst_1:
951                                 op_stack_push_unknown(be->stack);
952                                 op_stack_push_unknown(be->stack);
953                                 break;
954
955                         case BC_bipush:
956                         case BC_sipush:
957                                 op_stack_push_unknown(be->stack);
958                                 break;
959
960                         case BC_ldc1:
961                         case BC_ldc2:
962                                 op_stack_push_unknown(be->stack);
963                                 break;
964
965                         case BC_ldc2w:
966                                 op_stack_push_unknown(be->stack);
967                                 op_stack_push_unknown(be->stack);
968                                 break;
969
970                         case BC_iload:
971                         case BC_fload:
972                         case BC_iload_0:
973                         case BC_iload_1:
974                         case BC_iload_2:
975                         case BC_iload_3:
976                         case BC_fload_0:
977                         case BC_fload_1:
978                         case BC_fload_2:
979                         case BC_fload_3:
980                                 op_stack_push_unknown(be->stack);
981                                 break;
982
983                         case BC_dload:
984                         case BC_lload:
985                         case BC_lload_0:
986                         case BC_lload_1:
987                         case BC_lload_2:
988                         case BC_lload_3:
989                         case BC_dload_0:
990                         case BC_dload_1:
991                         case BC_dload_2:
992                         case BC_dload_3:
993                                 op_stack_push_unknown(be->stack);
994                                 op_stack_push_unknown(be->stack);
995                                 break;
996
997                         case BC_aload:
998                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, jcode_get_u1(jc)));
999                                 break;
1000
1001                         case BC_aload_0:
1002                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 0));
1003                                 break;
1004
1005                         case BC_aload_1:
1006                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 1));
1007                                 break;
1008
1009                         case BC_aload_2:
1010                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 2));
1011                                 break;
1012
1013                         case BC_aload_3:
1014                                 op_stack_push(be->stack, bc_escape_analysis_address_local(be, 3));
1015                                 break;
1016
1017                         case BC_iaload:
1018                         case BC_faload:
1019                         case BC_baload:
1020                         case BC_caload:
1021                         case BC_saload:
1022                                 op_stack_pop(be->stack);
1023                                 op_stack_pop(be->stack);
1024                                 op_stack_push_unknown(be->stack);
1025                                 break;
1026
1027                         case BC_laload:
1028                         case BC_daload:
1029                                 op_stack_pop(be->stack);
1030                                 op_stack_pop(be->stack);
1031                                 op_stack_push_unknown(be->stack);
1032                                 op_stack_push_unknown(be->stack);
1033                                 break;
1034
1035                         case BC_aaload:
1036                                 op_stack_pop(be->stack);
1037                                 op_stack_pop(be->stack);
1038                                 op_stack_push_unknown(be->stack);
1039                                 break;
1040
1041                         case BC_istore:
1042                         case BC_fstore:
1043                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1044                                 op_stack_pop(be->stack);
1045                                 break;
1046
1047                         case BC_istore_0:
1048                         case BC_fstore_0:
1049                                 bc_escape_analysis_dirty(be, 0);
1050                                 op_stack_pop(be->stack);
1051                                 break;
1052
1053                         case BC_istore_1:
1054                         case BC_fstore_1:
1055                                 bc_escape_analysis_dirty(be, 1);
1056                                 op_stack_pop(be->stack);
1057                                 break;
1058
1059                         case BC_istore_2:
1060                         case BC_fstore_2:
1061                                 bc_escape_analysis_dirty(be, 2);
1062                                 op_stack_pop(be->stack);
1063                                 break;
1064
1065                         case BC_istore_3:
1066                         case BC_fstore_3:
1067                                 bc_escape_analysis_dirty(be, 3);
1068                                 op_stack_pop(be->stack);
1069                                 break;
1070
1071                         case BC_lstore:
1072                         case BC_dstore:
1073                                 bc_escape_analysis_dirty_2(be, jcode_get_u1(jc));
1074                                 op_stack_pop(be->stack);
1075                                 op_stack_pop(be->stack);
1076                                 break;
1077
1078                         case BC_lstore_0:
1079                         case BC_dstore_0:
1080                                 bc_escape_analysis_dirty_2(be, 0);
1081                                 op_stack_pop(be->stack);
1082                                 op_stack_pop(be->stack);
1083                                 break;
1084
1085                         case BC_lstore_1:
1086                         case BC_dstore_1:
1087                                 bc_escape_analysis_dirty_2(be, 1);
1088                                 op_stack_pop(be->stack);
1089                                 op_stack_pop(be->stack);
1090                                 break;
1091
1092                         case BC_lstore_2:
1093                         case BC_dstore_2:
1094                                 bc_escape_analysis_dirty_2(be, 2);
1095                                 op_stack_pop(be->stack);
1096                                 op_stack_pop(be->stack);
1097                                 break;
1098
1099                         case BC_lstore_3:
1100                         case BC_dstore_3:
1101                                 bc_escape_analysis_dirty_2(be, 3);
1102                                 op_stack_pop(be->stack);
1103                                 op_stack_pop(be->stack);
1104                                 break;
1105
1106                         case BC_astore:
1107                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1108                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1109                                 break;
1110
1111                         case BC_astore_0:
1112                                 bc_escape_analysis_dirty(be, 0);
1113                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1114                                 break;
1115
1116                         case BC_astore_1:
1117                                 bc_escape_analysis_dirty(be, 1);
1118                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1119                                 break;
1120
1121                         case BC_astore_2:
1122                                 bc_escape_analysis_dirty(be, 2);
1123                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1124                                 break;
1125
1126                         case BC_astore_3:
1127                                 bc_escape_analysis_dirty(be, 3);
1128                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1129                                 break;
1130
1131                         case BC_iastore:
1132                         case BC_fastore:
1133                         case BC_bastore:
1134                         case BC_castore:
1135                         case BC_sastore:
1136                                 op_stack_pop(be->stack);
1137                                 op_stack_pop(be->stack);
1138                                 op_stack_pop(be->stack);
1139                                 break;
1140
1141                         case BC_lastore:
1142                         case BC_dastore:
1143                                 op_stack_pop(be->stack);
1144                                 op_stack_pop(be->stack);
1145                                 op_stack_pop(be->stack);
1146                                 op_stack_pop(be->stack);
1147                                 break;
1148
1149                         case BC_aastore:
1150                                 op_stack_pop(be->stack);
1151                                 op_stack_pop(be->stack);
1152                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1153                                 break;
1154
1155                         case BC_pop:
1156                                 op_stack_pop(be->stack);
1157                                 break;
1158
1159                         case BC_pop2:
1160                                 op_stack_pop(be->stack);
1161                                 op_stack_pop(be->stack);
1162                                 break;
1163
1164                         case BC_dup:
1165                                 value1 = op_stack_get(be->stack, 1);
1166                                 op_stack_push(be->stack, value1);
1167                                 break;
1168
1169                         case BC_dup_x1:
1170                                 value1 = op_stack_pop(be->stack);
1171                                 value2 = op_stack_pop(be->stack);
1172                                 op_stack_push(be->stack, value1);
1173                                 op_stack_push(be->stack, value2);
1174                                 op_stack_push(be->stack, value1);
1175                                 break;
1176
1177                         case BC_dup_x2:
1178                                 value1 = op_stack_pop(be->stack);
1179                                 value2 = op_stack_pop(be->stack);
1180                                 value3 = op_stack_pop(be->stack);
1181                                 op_stack_push(be->stack, value1);
1182                                 op_stack_push(be->stack, value3);
1183                                 op_stack_push(be->stack, value2);
1184                                 op_stack_push(be->stack, value1);
1185                                 break;
1186                                 
1187                         case BC_dup2:
1188                                 value1 = op_stack_get(be->stack, 1);
1189                                 value2 = op_stack_get(be->stack, 2);
1190                                 op_stack_push(be->stack, value2);
1191                                 op_stack_push(be->stack, value1);
1192                                 break;
1193
1194                         case BC_dup2_x1:
1195                                 value1 = op_stack_pop(be->stack);
1196                                 value2 = op_stack_pop(be->stack);
1197                                 value3 = op_stack_pop(be->stack);
1198                                 op_stack_push(be->stack, value2);
1199                                 op_stack_push(be->stack, value1);
1200                                 op_stack_push(be->stack, value3);
1201                                 op_stack_push(be->stack, value2);
1202                                 op_stack_push(be->stack, value1);
1203                                 break;
1204
1205                         case BC_dup2_x2:
1206                                 value1 = op_stack_pop(be->stack);
1207                                 value2 = op_stack_pop(be->stack);
1208                                 value3 = op_stack_pop(be->stack);
1209                                 value4 = op_stack_pop(be->stack);
1210                                 op_stack_push(be->stack, value2);
1211                                 op_stack_push(be->stack, value1);
1212                                 op_stack_push(be->stack, value4);
1213                                 op_stack_push(be->stack, value3);
1214                                 op_stack_push(be->stack, value2);
1215                                 op_stack_push(be->stack, value1);
1216                                 break;
1217
1218                         case BC_swap:
1219                                 value1 = op_stack_get(be->stack, 1);
1220                                 value2 = op_stack_get(be->stack, 2);
1221                                 op_stack_set(be->stack, 1, value2);
1222                                 op_stack_set(be->stack, 2, value1);
1223                                 break;
1224
1225                         case BC_iadd:
1226                         case BC_fadd:
1227
1228                         case BC_isub:
1229                         case BC_fsub:
1230
1231                         case BC_imul:
1232                         case BC_fmul:
1233
1234                         case BC_idiv:
1235                         case BC_fdiv:
1236
1237                         case BC_irem:
1238                         case BC_frem:
1239
1240                                 op_stack_pop(be->stack);
1241                                 op_stack_pop(be->stack);
1242                                 op_stack_push_unknown(be->stack);
1243                                 break;
1244
1245                         case BC_ladd:
1246                         case BC_dadd:
1247
1248                         case BC_lsub:
1249                         case BC_dsub:
1250
1251                         case BC_ldiv:
1252                         case BC_ddiv:
1253
1254                         case BC_lmul:
1255                         case BC_dmul:
1256
1257                         case BC_lrem:
1258                         case BC_drem:
1259
1260                                 op_stack_pop(be->stack);
1261                                 op_stack_pop(be->stack);
1262                                 op_stack_pop(be->stack);
1263                                 op_stack_pop(be->stack);
1264                                 op_stack_push_unknown(be->stack);
1265                                 op_stack_push_unknown(be->stack);
1266                                 break;
1267
1268                         case BC_ineg:
1269                         case BC_lneg:
1270                         case BC_fneg:
1271                         case BC_dneg:
1272
1273                                 /* Nothing */
1274                                 break;
1275
1276                         case BC_ishl:
1277                         case BC_ishr:
1278                         case BC_iushr:
1279                                 op_stack_pop(be->stack);
1280                                 op_stack_pop(be->stack);
1281                                 op_stack_push_unknown(be->stack);
1282                                 break;
1283
1284                         case BC_lshl:
1285                         case BC_lshr:
1286                         case BC_lushr:
1287                                 op_stack_pop(be->stack);
1288                                 op_stack_pop(be->stack);
1289                                 /* Second operand is int. */
1290                                 op_stack_pop(be->stack);
1291                                 op_stack_push_unknown(be->stack);
1292                                 op_stack_push_unknown(be->stack);
1293                                 break;
1294
1295                         case BC_iand:
1296                         case BC_ior:
1297                         case BC_ixor:
1298                                 op_stack_pop(be->stack);
1299                                 op_stack_pop(be->stack);
1300                                 op_stack_push_unknown(be->stack);
1301                                 break;
1302
1303                         case BC_land:
1304                         case BC_lor:
1305                         case BC_lxor:
1306                                 op_stack_pop(be->stack);
1307                                 op_stack_pop(be->stack);
1308                                 op_stack_pop(be->stack);
1309                                 op_stack_pop(be->stack);
1310                                 op_stack_push_unknown(be->stack);
1311                                 op_stack_push_unknown(be->stack);
1312                                 break;
1313
1314                         case BC_iinc:
1315                                 /* Not stack operation. */
1316                                 bc_escape_analysis_dirty(be, jcode_get_u1(jc));
1317                                 break;
1318
1319                         case BC_i2l:
1320                         case BC_i2d:
1321                                 op_stack_pop(be->stack);
1322                                 op_stack_push_unknown(be->stack);
1323                                 op_stack_push_unknown(be->stack);
1324                                 break;
1325
1326                         case BC_i2f:
1327                                 op_stack_pop(be->stack);
1328                                 op_stack_push_unknown(be->stack);
1329                                 break;
1330
1331                         case BC_l2i:
1332                         case BC_l2f:
1333                                 op_stack_pop(be->stack);
1334                                 op_stack_pop(be->stack);
1335                                 op_stack_push_unknown(be->stack);
1336                                 break;
1337
1338                         case BC_l2d:
1339                                 op_stack_pop(be->stack);
1340                                 op_stack_pop(be->stack);
1341                                 op_stack_push_unknown(be->stack);
1342                                 op_stack_push_unknown(be->stack);
1343                                 break;
1344
1345                         case BC_f2i:
1346                                 op_stack_pop(be->stack);
1347                                 op_stack_push_unknown(be->stack);
1348                                 break;
1349                                 
1350                         case BC_f2l:
1351                         case BC_f2d:
1352                                 op_stack_pop(be->stack);
1353                                 op_stack_push_unknown(be->stack);
1354                                 op_stack_push_unknown(be->stack);
1355                                 break;
1356
1357                         case BC_d2i:
1358                         case BC_d2f:
1359                                 op_stack_pop(be->stack);
1360                                 op_stack_pop(be->stack);
1361                                 op_stack_push_unknown(be->stack);
1362                                 break;
1363
1364                         case BC_d2l:
1365                                 op_stack_pop(be->stack);
1366                                 op_stack_pop(be->stack);
1367                                 op_stack_push_unknown(be->stack);
1368                                 op_stack_push_unknown(be->stack);
1369                                 break;
1370
1371                         case BC_int2byte:
1372                         case BC_int2char:
1373                         case BC_int2short:
1374                                 op_stack_pop(be->stack);
1375                                 op_stack_push_unknown(be->stack);
1376                                 break;
1377
1378                         case BC_fcmpl:
1379                         case BC_fcmpg:
1380                                 op_stack_pop(be->stack);
1381                                 op_stack_pop(be->stack);
1382                                 op_stack_push_unknown(be->stack);
1383                                 break;
1384
1385                         case BC_lcmp:
1386                         case BC_dcmpl:
1387                         case BC_dcmpg:
1388                                 op_stack_pop(be->stack);
1389                                 op_stack_pop(be->stack);
1390                                 op_stack_pop(be->stack);
1391                                 op_stack_pop(be->stack);
1392                                 op_stack_push_unknown(be->stack);
1393                                 break;
1394
1395                         case BC_ifeq:
1396                         case BC_ifne:
1397                         case BC_iflt:
1398                         case BC_ifge:
1399                         case BC_ifgt:
1400                         case BC_ifle:
1401                                 op_stack_pop(be->stack);
1402                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1403                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1404                                 bb_end = true;
1405                                 break;
1406
1407                         case BC_if_icmpeq:
1408                         case BC_if_icmpne:
1409                         case BC_if_icmplt:
1410                         case BC_if_icmpge:
1411                         case BC_if_icmpgt:
1412                         case BC_if_icmple:
1413                                 op_stack_pop(be->stack);
1414                                 op_stack_pop(be->stack);
1415                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1416                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1417                                 bb_end = true;
1418                                 break;
1419
1420                         case BC_if_acmpeq:
1421                         case BC_if_acmpne:
1422                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1423                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1424                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1425                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1426                                 bb_end = true;
1427                                 break;
1428
1429                         case BC_goto:
1430                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1431                                 bb_end = true;
1432                                 break;
1433
1434                         case BC_jsr:
1435                                 op_stack_push_unknown(be->stack);
1436                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1437                                 bb_end = true;
1438                                 break;
1439
1440                         case BC_ret:
1441                                 break;
1442
1443                         case BC_tableswitch:
1444                                 op_stack_pop(be->stack);
1445                                 jcode_rewind_instruction(jc);
1446                                 bc_escape_analysis_parse_tableswitch(be, jc);
1447                                 length = jcode_get_instruction_length(jc);
1448                                 bb_end = 1;
1449                                 break;
1450
1451                         case BC_lookupswitch:
1452                                 op_stack_pop(be->stack);
1453                                 jcode_rewind_instruction(jc);
1454                                 bc_escape_analysis_parse_lookupswitch(be, jc);
1455                                 length = jcode_get_instruction_length(jc);
1456                                 bb_end = 1;
1457                                 break;
1458
1459                         case BC_return:
1460                                 bb_end = true;
1461                                 break;
1462
1463                         case BC_ireturn:
1464                         case BC_freturn:
1465                                 op_stack_pop(be->stack);
1466                                 bb_end = true;
1467                                 break;
1468
1469                         case BC_lreturn:
1470                         case BC_dreturn:
1471                                 op_stack_pop(be->stack);
1472                                 op_stack_pop(be->stack);
1473                                 bb_end = true;
1474                                 break;
1475
1476                         case BC_areturn:
1477                                 /* FIXME */
1478                                 bc_escape_analysis_returned(be, op_stack_pop(be->stack));
1479                                 bb_end = true;
1480                                 break;
1481
1482                         case BC_getfield:
1483                                 op_stack_pop(be->stack);
1484                                 /* Fall through. */
1485
1486                         case BC_getstatic:
1487                                 if (
1488                                         bc_escape_analysis_value_category(be, jcode_get_s2(jc)) == 
1489                                         VALUE_CATEGORY_2
1490                                 ) {
1491                                         op_stack_push_unknown(be->stack);
1492                                 }
1493                                 op_stack_push_unknown(be->stack);
1494                                 break;
1495
1496                         
1497                         case BC_putfield:
1498                                 if (
1499                                         bc_escape_analysis_value_category(be, jcode_get_u2(jc)) == 
1500                                         VALUE_CATEGORY_2
1501                                 ) {
1502                                         op_stack_pop(be->stack);
1503
1504                                         op_stack_pop(be->stack);
1505                                         op_stack_pop(be->stack);
1506                                 } else {
1507                                         value2 = op_stack_pop(be->stack);
1508                                         value1 = op_stack_pop(be->stack);
1509                                         bc_escape_analysis_adjust_state(be, value2, ESCAPE_GLOBAL);
1510                                 }
1511                                 break;
1512
1513                         case BC_putstatic:
1514                                 if (
1515                                         bc_escape_analysis_value_category(be, jcode_get_u2(jc)) == 
1516                                         VALUE_CATEGORY_2
1517                                 ) {
1518                                         op_stack_pop(be->stack);
1519                                         op_stack_pop(be->stack);
1520                                 } else {
1521                                         value1 = op_stack_pop(be->stack);
1522                                         bc_escape_analysis_adjust_state(be, value1, ESCAPE_GLOBAL);
1523                                 }
1524                                 break;
1525
1526                         case BC_invokevirtual:
1527                         case BC_invokespecial:
1528                         case BC_invokestatic:
1529                         case BC_invokeinterface:
1530                                 jcode_rewind_instruction(jc);
1531                                 bc_escape_analysis_parse_invoke(be, jc);
1532                                 break;
1533
1534                         case BC_new:
1535                                 op_stack_push_unknown(be->stack);
1536                                 break;
1537
1538                         case BC_newarray:
1539                         case BC_anewarray:
1540                                 op_stack_pop(be->stack);
1541                                 op_stack_push_unknown(be->stack);
1542                                 break;
1543
1544                         case BC_arraylength:
1545                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_METHOD);
1546                                 op_stack_push_unknown(be->stack);
1547                                 break;
1548
1549                         case BC_athrow:
1550                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1551                                 bb_end = true;
1552                                 break;
1553
1554                         case BC_checkcast:
1555                                 value1 = op_stack_get(be->stack, 1);
1556                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1557                                 break;
1558
1559                         case BC_instanceof:
1560                                 value1 = op_stack_pop(be->stack);
1561                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1562                                 op_stack_push_unknown(be->stack);
1563                                 break;
1564
1565                         case BC_monitorenter:
1566                         case BC_monitorexit:
1567                                 value1 = op_stack_pop(be->stack);
1568                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1569                                 break;
1570
1571                         case BC_wide:
1572
1573                                 /* All except iinc have a length of 4. */
1574                                 length = 4;
1575
1576                                 switch (jcode_get_u1(jc)) {
1577                                         case BC_iload:
1578                                         case BC_fload:
1579                                                 op_stack_push_unknown(be->stack);
1580                                                 break;
1581
1582                                         case BC_lload:
1583                                         case BC_dload:
1584                                                 op_stack_push_unknown(be->stack);
1585                                                 op_stack_push_unknown(be->stack);
1586                                                 break;
1587
1588                                         case BC_aload:
1589                                                 op_stack_push(
1590                                                         be->stack, 
1591                                                         bc_escape_analysis_address_local(
1592                                                                 be, 
1593                                                                 jcode_get_u1(jc)
1594                                                         )
1595                                                 );
1596                                                 break;
1597
1598                                         case BC_istore:
1599                                         case BC_fstore:
1600                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1601                                                 op_stack_pop(be->stack);
1602                                                 break;
1603
1604                                         case BC_lstore:
1605                                         case BC_dstore:
1606                                                 bc_escape_analysis_dirty_2(be, jcode_get_u2(jc));
1607                                                 op_stack_pop(be->stack);
1608                                                 op_stack_pop(be->stack);
1609                                                 break;
1610
1611                                         case BC_astore:
1612                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1613                                                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1614                                                 break;
1615                                                 
1616                                         case BC_ret:
1617                                                 /* Do nothing. */
1618                                                 break;
1619
1620                                         case BC_iinc:
1621                                                 bc_escape_analysis_dirty(be, jcode_get_u2(jc));
1622                                                 length = 6;
1623                                                 /* Do nothing. */
1624                                                 break;
1625                                 }
1626                                 break;
1627
1628                         case BC_multianewarray:
1629                                 jcode_get_u2(jc);
1630                                 dim = jcode_get_u1(jc);
1631                                 while (dim-- > 0) {
1632                                         op_stack_pop(be->stack);
1633                                 }
1634                                 op_stack_push_unknown(be->stack);
1635                                 break;
1636
1637                         case BC_ifnull:
1638                         case BC_ifnonnull:
1639                                 value1 = op_stack_pop(be->stack);
1640                                 bc_escape_analysis_adjust_state(be, value1, ESCAPE_METHOD);
1641                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target(jc));
1642                                 bc_escape_analysis_branch_target(be, jcode_get_fall_through_target(jc));
1643                                 bb_end = true;
1644                                 break;
1645
1646                         case BC_goto_w:
1647                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target_wide(jc));
1648                                 bb_end = true;
1649                                 break;
1650
1651                         case BC_jsr_w:
1652                                 bc_escape_analysis_branch_target(be, jcode_get_branch_target_wide(jc));
1653                                 bb_end = true;
1654                                 break;
1655
1656                         case BC_breakpoint:
1657                         case BC_impdep1:
1658                         case BC_impdep2:
1659                                 break;
1660
1661                         default:
1662                                 break;
1663                 }
1664                 assert(length > 0);
1665                 jcode_forward_instruction_relative(jc, length);
1666
1667 #if BC_ESCAPE_VERBOSE
1668                 if (be->verbose) {
1669                         op_stack_print(be->stack, stdout);
1670                         printf("\n");
1671                 }
1672 #endif
1673         }
1674
1675 #if BC_ESCAPE_VERBOSE
1676         if (be->verbose) {
1677                 dprintf(be->depth, "Elements left on stack: %d\n", op_stack_element_count(be->stack));
1678         }
1679 #endif
1680
1681         while ((! op_stack_is_empty(be->stack)) && (! be->fatal_error)) {
1682 #if BC_ESCAPE_VERBOSE
1683                 if (be->verbose) {
1684                         dprintf(be->depth, "Stack element: ");
1685                         op_stack_print(be->stack, stdout);
1686                         printf(" => ");
1687                 }
1688 #endif
1689                 bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
1690 #if BC_ESCAPE_VERBOSE
1691                 if (be->verbose) {
1692                         op_stack_print(be->stack, stdout);
1693                         printf("\n");
1694                 }
1695 #endif
1696         }
1697
1698         if (be->fatal_error) {
1699 #if BC_ESCAPE_VERBOSE
1700                 if (be->verbose) {
1701                         printf("Fatal error while processing basic block. Aborting.\n");
1702                 }
1703 #endif
1704                 assert(0);
1705         }
1706 }
1707
1708 static void     bc_escape_analysis_adjust_return_value(bc_escape_analysis_t *be) {
1709         escape_state_t re, pe;
1710         int i;
1711
1712         /* Only calculate, if return value is of type address. */
1713
1714         if (be->method->parseddesc->returntype.type != TYPE_ADR) {
1715                 return ;
1716         }
1717
1718         /* If a parameter can be returned, adjust to its escape state. */
1719
1720         for (i = 0; i < be->param_escape_size; ++i) {
1721                 if (bit_vector_get(be->adr_param_returned, i)) {
1722                         be->param_escape[i] |= 0x80;
1723
1724                         pe = escape_state_from_u1(be->param_escape[i]);
1725                         re = escape_state_from_u1(be->param_escape[-1]);
1726                         
1727                         if (pe > re) {
1728                                 be->param_escape[-1] = escape_state_to_u1(pe);
1729                         }
1730                 }
1731         }
1732 }
1733
1734 static void bc_escape_analysis_analyze(bc_escape_analysis_t *be) {
1735         raw_exception_entry *itee;
1736         basicblock_work_item_t *bb;
1737         jcode_t jc;
1738
1739         /* Add root as basic block. */
1740
1741         bc_escape_analysis_branch_target(be, 0);
1742
1743         /* Add each exception handler as basic block. */
1744
1745         for (
1746                 itee = be->method->rawexceptiontable;
1747                 itee != be->method->rawexceptiontable + be->method->rawexceptiontablelength;
1748                 ++itee
1749         ) {
1750                 bc_escape_analysis_branch_target(be, itee->handlerpc);
1751         }
1752
1753         /* Init jcode parser. */
1754
1755         jcode_init(
1756                 &jc,
1757                 be->method->jcode,
1758                 be->method->jcodelength,
1759                 0,
1760                 &(be->fatal_error)
1761         );
1762
1763         /* Process basicblock by basicblock. */
1764
1765         for (bb = be->basicblocks->first; bb; bb = bb->next) {
1766                 jcode_move_to_index(&jc, bb->bytecode_index);
1767                 bc_escape_analysis_process_basicblock(
1768                         be,
1769                         &jc
1770                 );
1771         }
1772
1773         /* Calculate escape of return value. */
1774
1775         bc_escape_analysis_adjust_return_value(be);
1776
1777         /* Export escape of parameters. */
1778
1779         be->method->paramescape = be->param_escape;
1780 }
1781
1782 static void bc_escape_analysis_perform_intern(methodinfo *m, int depth) {
1783         bc_escape_analysis_t *be;
1784         bool verbose = false;
1785
1786 #if BC_ESCAPE_VERBOSE
1787         if (verbose) {
1788                 dprintf(
1789                         depth,
1790                         "=== BC escape analysis of %s/%s at depth %d ===\n",
1791                         m->clazz->name->text,
1792                         m->name->text,
1793                         depth
1794                 );
1795         }
1796 #endif
1797
1798         if (depth >= 3) {
1799                 return;
1800         }
1801
1802         if (m->paramescape != NULL) {
1803 #if BC_ESCAPE_VERBOSE
1804                 if (verbose) {  
1805                         dprintf(depth, "Escape info for method already available.\n");
1806                 }
1807 #endif
1808                 return;
1809         }
1810
1811         if ((m->flags & ACC_METHOD_EA) != 0) {
1812 #if BC_ESCAPE_VERBOSE
1813                 if (verbose) {  
1814                         dprintf(depth, "Detected recursion, aborting.\n");
1815                 }
1816 #endif
1817                 return;
1818         }
1819
1820         if (m->jcode == NULL) {
1821 #if BC_ESCAPE_VERBOSE
1822                 if (verbose) {
1823                         dprintf(depth, "No bytecode for callee.\n");
1824                 }
1825 #endif
1826                 return;
1827         }
1828
1829         if (m->jcodelength > 250) {
1830 #if BC_ESCAPE_VERBOSE
1831                 if (verbose) {
1832                         dprintf(depth, "Bytecode too long: %d.\n", m->jcodelength);
1833                 }
1834 #endif
1835                 return;
1836         }
1837
1838         be = DNEW(bc_escape_analysis_t);
1839         bc_escape_analysis_init(be, m, verbose, depth);
1840
1841         m->flags |= ACC_METHOD_EA;
1842
1843         bc_escape_analysis_analyze(be);
1844
1845 #if BC_ESCAPE_VERBOSE
1846         if (be->verbose) {
1847                 dprintf(
1848                         depth,
1849                         "%s/%s: Non-escaping params: %d\n", 
1850                         m->clazz->name->text,
1851                         m->name->text,
1852                         be->non_escaping_adr_params
1853                 );
1854         }
1855 #endif
1856
1857         m->flags &= ~ACC_METHOD_EA;
1858 }
1859
1860 void bc_escape_analysis_perform(methodinfo *m) {
1861         bc_escape_analysis_perform_intern(m, 0);
1862 }
1863
1864
1865
1866 /*
1867  * These are local overrides for various environment variables in Emacs.
1868  * Please do not remove this and leave it at the end of the file, where
1869  * Emacs will automagically detect them.
1870  * ---------------------------------------------------------------------
1871  * Local variables:
1872  * mode: c
1873  * indent-tabs-mode: t
1874  * c-basic-offset: 4
1875  * tab-width: 4
1876  * End:
1877  * vim:noexpandtab:sw=4:ts=4:
1878  */
1879