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