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