1 /* src/vm/optimizing/escape.c
4 CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
6 This file is part of CACAO.
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.
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.
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
24 #include "vm/jit/jit.h"
25 #include "vmcore/class.h"
26 #include "vm/jit/optimizing/escape.h"
28 /*** escape_state *************************************************************/
30 const char *escape_state_to_string(escape_state_t escape_state) {
31 # define str(x) case x: return #x;
32 switch (escape_state) {
36 str(ESCAPE_GLOBAL_THROUGH_METHOD)
38 default: return "???";
43 /*** instruction **************************************************************/
45 static inline s2 instruction_get_opcode(const instruction *iptr) {
46 if (iptr->opc == ICMD_BUILTIN) {
47 return iptr->sx.s23.s3.bte->opcode;
53 static inline bool instruction_is_unresolved(const instruction *iptr) {
54 return iptr->flags.bits & INS_FLAG_UNRESOLVED;
57 static inline s4 instruction_field_type(const instruction *iptr) {
58 if (instruction_is_unresolved(iptr)) {
59 return iptr->sx.s23.s3.uf->fieldref->parseddesc.fd->type;
61 return iptr->sx.s23.s3.fmiref->p.field->type;
65 static inline s4 instruction_s1(const instruction *iptr) {
66 return iptr->s1.varindex;
69 static inline s4 instruction_s2(const instruction *iptr) {
70 return iptr->sx.s23.s2.varindex;
73 static inline s4 instruction_s3(const instruction *iptr) {
74 return iptr->sx.s23.s3.varindex;
77 static inline s4 instruction_dst(const instruction *iptr) {
78 return iptr->dst.varindex;
81 static inline s4 instruction_arg(const instruction *iptr, int arg) {
82 return iptr->sx.s23.s2.args[arg];
85 static inline bool instruction_is_class_constant(const instruction *iptr) {
86 return iptr->flags.bits & INS_FLAG_CLASS;
89 static inline classinfo *instruction_classinfo(const instruction *iptr) {
90 return iptr->sx.val.c.cls;
93 static inline methodinfo *instruction_local_methodinfo(const instruction *iptr) {
94 if (instruction_is_unresolved(iptr)) {
97 return iptr->sx.s23.s3.fmiref->p.method;
101 static inline int instruction_dst_type(const instruction *iptr, jitdata *jd) {
102 return VAROP(iptr->dst)->type;
105 static inline int instruction_return_type(const instruction *iptr) {
106 return instruction_call_site(iptr)->returntype.type;
109 static inline s4 instruction_arg_type(const instruction *iptr, int arg) {
110 methoddesc *md = instruction_call_site(iptr);
111 assert(0 <= arg && arg < md->paramcount);
112 return md->paramtypes[arg].type;
115 static inline int instruction_arg_count(const instruction *iptr) {
116 return instruction_call_site(iptr)->paramcount;
119 /*** instruction_list ********************************************************/
121 typedef struct instruction_list_item {
123 struct instruction_list_item *next;
124 } instruction_list_item_t;
127 instruction_list_item_t *first;
128 } instruction_list_t;
130 void instruction_list_init(instruction_list_t *list) {
134 void instruction_list_add(instruction_list_t *list, instruction *instr) {
135 instruction_list_item_t *item = DNEW(instruction_list_item_t);
137 item->next = list->first;
141 #define FOR_EACH_INSTRUCTION_LIST(list, it) \
142 for ((it) = (list)->first; (it) != NULL; (it) = (it)->next)
144 /*** escape_analysis *********************************************************/
151 instruction_list_t *allocations;
152 instruction_list_t *getfields;
154 struct var_extra **var;
156 unsigned adr_args_count;
162 /*** dependency_list_item ****************************************************/
164 typedef struct dependency_list_item {
166 struct dependency_list_item *next;
167 } dependency_list_item_t;
169 bool dependency_list_item_compare(const dependency_list_item_t *item, const instruction *load) {
171 instruction *store = item->store;
175 if (load->opc == ICMD_AALOAD) {
177 if (store->opc != ICMD_AASTORE) {
185 if (store->opc != ICMD_PUTFIELD) {
190 instruction_is_unresolved(store) !=
191 instruction_is_unresolved(load)
196 if (instruction_is_unresolved(store)) {
197 storen = store->sx.s23.s3.uf->fieldref->name;
198 loadn = load->sx.s23.s3.uf->fieldref->name;
200 storen = store->sx.s23.s3.fmiref->name;
201 loadn = load->sx.s23.s3.fmiref->name;
204 /* TODO pointer equality ? */
206 if (storen->blength != loadn->blength) {
210 return (strcmp(storen->text, loadn->text) == 0);
215 s4 dependency_list_item_get_dependency(const dependency_list_item_t *item) {
216 switch (item->store->opc) {
218 return instruction_s3(item->store);
220 return instruction_s2(item->store);
227 /*** dependency_list *********************************************************/
230 dependency_list_item_t *first;
231 dependency_list_item_t *last;
234 void dependency_list_init(dependency_list_t *dl) {
239 void dependency_list_add(dependency_list_t *dl, instruction *store) {
240 dependency_list_item_t *item = DNEW(dependency_list_item_t);
245 if (dl->first == NULL) {
249 dl->last->next = item;
254 void dependenCy_list_import(dependency_list_t *dl, dependency_list_t *other) {
260 if (dl->first == NULL) {
263 dl->last->next = other->first;
264 dl->last = other->last;
272 #define FOR_EACH_DEPENDENCY_LIST(dl, it) \
273 for ((it) = (dl)->first; (it) != NULL; (it) = (it)->next)
275 /*** var_extra ***************************************************************/
277 typedef struct var_extra {
278 instruction *allocation;
279 escape_state_t escape_state;
281 dependency_list_t *dependency_list;
282 bool is_arg; /* TODO optimize */
285 static void var_extra_init(var_extra_t *ve) {
286 ve->allocation = NULL;
287 ve->escape_state = ESCAPE_NONE;
288 ve->representant = -1;
289 ve->dependency_list = NULL;
293 static inline var_extra_t *var_extra_get_no_alloc(const escape_analysis_t *e, s4 var) {
297 static var_extra_t* var_extra_get(escape_analysis_t *e, s4 var) {
300 assert(0 <= var && var <= e->jd->vartop);
302 ve = var_extra_get_no_alloc(e, var);
305 ve = DNEW(var_extra_t);
313 static s4 var_extra_get_representant(escape_analysis_t *e, s4 var) {
319 ve = var_extra_get(e, var);
321 while (ve->representant != -1) {
322 assert(ctr++ < 10000);
323 var = ve->representant;
324 ve = var_extra_get_no_alloc(e, var);
331 static escape_state_t var_extra_get_escape_state(escape_analysis_t *e, s4 var) {
334 var = var_extra_get_representant(e, var);
335 ve = var_extra_get(e, var);
337 return ve->escape_state;
340 static void var_extra_set_escape_state(escape_analysis_t *e, s4 var, escape_state_t escape_state) {
343 var = var_extra_get_representant(e, var);
344 ve = var_extra_get(e, var);
346 ve->escape_state = escape_state;
349 static dependency_list_t *var_extra_get_dependency_list(escape_analysis_t *e, s4 var) {
352 var = var_extra_get_representant(e, var);
353 ve = var_extra_get(e, var);
355 if (ve->dependency_list == NULL) {
356 ve->dependency_list = DNEW(dependency_list_t);
357 dependency_list_init(ve->dependency_list);
360 return ve->dependency_list;
363 /*** escape_analysis *********************************************************/
365 static void escape_analysis_init(escape_analysis_t *e, jitdata *jd) {
368 e->allocations = DNEW(instruction_list_t);
369 instruction_list_init(e->allocations);
371 e->getfields = DNEW(instruction_list_t);
372 instruction_list_init(e->getfields);
374 e->var = DMNEW(var_extra_t *, jd->vartop);
375 MZERO(e->var, var_extra_t *, jd->vartop);
377 e->adr_args_count = 0;
380 strcmp(e->jd->m->clazz->name->text, "gnu/java/util/regex/RESyntax") == 0
381 && strcmp(e->jd->m->name->text, "<clinit>") == 0
386 static void escape_analysis_set_allocation(escape_analysis_t *e, s4 var, instruction *iptr) {
387 var_extra_get(e, var)->allocation = iptr;
390 static instruction *escape_analysis_get_allocation(const escape_analysis_t *e, s4 var) {
391 var_extra_t *ve = var_extra_get_no_alloc(e, var);
394 assert(ve->allocation != NULL);
396 return ve->allocation;
399 static void escape_analysis_set_is_argument(escape_analysis_t *e, s4 var) {
400 var_extra_get(e, var)->is_arg = true;
403 static bool escape_analysis_get_is_argument(escape_analysis_t *e, s4 var) {
404 return var_extra_get(e, var)->is_arg;
407 static void escape_analysis_ensure_state(escape_analysis_t *e, s4 var, escape_state_t escape_state) {
410 dependency_list_item_t *it;
412 var = var_extra_get_representant(e, var);
413 ve = var_extra_get(e, var);
415 if (ve->escape_state < escape_state) {
418 "escape state of %d %s => %s\n",
420 escape_state_to_string(ve->escape_state),
421 escape_state_to_string(escape_state)
424 ve->escape_state = escape_state;
425 if (ve->dependency_list != NULL) {
426 FOR_EACH_DEPENDENCY_LIST(ve->dependency_list, it) {
428 printf("propagating to %s@%d\n", icmd_table[it->store->opc].name, it->store->line);
430 escape_analysis_ensure_state(
432 dependency_list_item_get_dependency(it),
440 static escape_state_t escape_analysis_get_state(escape_analysis_t *e, s4 var) {
441 return var_extra_get_escape_state(e, var);
444 #define escape_analysis_assert_has_escape(e, var) \
446 var_extra_get_no_alloc(e, var) && \
447 (var_extra_get_no_alloc(e, var)->escape_state > ESCAPE_UNKNOWN) \
450 static classinfo *escape_analysis_classinfo_in_var(escape_analysis_t *e, s4 var) {
451 instruction *iptr = escape_analysis_get_allocation(e, var);
457 if (! instruction_is_class_constant(iptr)) {
461 if (instruction_dst(iptr) != var) {
465 if (instruction_is_unresolved(iptr)) {
469 return instruction_classinfo(iptr);
472 static void escape_analysis_merge(escape_analysis_t *e, s4 var1, s4 var2) {
474 var_extra_t *ve1, *ve2;
475 dependency_list_item_t *itd;
478 var1 = var_extra_get_representant(e, var1);
479 var2 = var_extra_get_representant(e, var2);
481 /* Don't merge the same escape sets. */
487 ve1 = var_extra_get(e, var1);
488 ve2 = var_extra_get(e, var2);
490 /* Adjust escape state to maximal escape state. */
492 escape_analysis_ensure_state(e, var1, ve2->escape_state);
493 escape_analysis_ensure_state(e, var2, ve1->escape_state);
495 /* Representant of var1 becomes the representant of var2. */
497 ve2->representant = var1;
499 /* Adjust is_argument to logical or. */
501 has_become_arg = ve1->is_arg != ve2->is_arg;
502 ve1->is_arg = ve1->is_arg || ve2->is_arg;
504 if (e->verbose && has_become_arg) printf("(%d,%d) has become arg.\n", var1, var2);
506 /* Merge list of dependencies. */
508 if (ve1->dependency_list == NULL) {
509 ve1->dependency_list = ve2->dependency_list;
511 dependenCy_list_import(ve1->dependency_list, ve2->dependency_list);
514 /* If one of the merged values is an argument but the other not,
515 all dependencies of the newly created value escape globally. */
517 if (has_become_arg && ve1->dependency_list != NULL) {
518 FOR_EACH_DEPENDENCY_LIST(ve1->dependency_list, itd) {
519 escape_analysis_ensure_state(
521 dependency_list_item_get_dependency(itd),
528 static void escape_analysis_add_dependency(escape_analysis_t *e, instruction *store) {
529 s4 obj = instruction_s1(store);
530 dependency_list_t *dl = var_extra_get_dependency_list(e, obj);
532 assert(store->opc == ICMD_PUTFIELD || store->opc == ICMD_AASTORE);
534 dependency_list_add(dl, store);
537 printf("dependency_list_add\n");
541 static void escape_analysis_process_instruction(escape_analysis_t *e, instruction *iptr) {
548 constant_FMIref *fmi;
550 resolve_result_t result;
553 printf("processing %s@%d\n", icmd_table[iptr->opc].name, iptr->line);
556 switch (instruction_get_opcode(iptr)) {
559 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
560 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
565 c = escape_analysis_classinfo_in_var(e, instruction_arg(iptr, 0));
567 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
570 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
571 if (e->verbose) printf("1\n");
572 } else if (c->finalizer != NULL) {
573 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
574 if (e->verbose) printf("3\n");
576 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
577 if (e->verbose) printf("2\n");
580 instruction_list_add(e->allocations, iptr);
587 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
588 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
589 instruction_list_add(e->allocations, iptr);
594 if (instruction_field_type(iptr) == TYPE_ADR) {
596 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
598 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
603 if (instruction_field_type(iptr) == TYPE_ADR) {
605 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
606 escape_analysis_assert_has_escape(e, instruction_s2(iptr));
608 if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
609 escape_analysis_ensure_state(e, instruction_s2(iptr), ESCAPE_GLOBAL);
611 escape_analysis_ensure_state(e, instruction_s2(iptr), escape_analysis_get_state(e, instruction_s1(iptr)));
612 escape_analysis_add_dependency(e, iptr);
619 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
620 escape_analysis_assert_has_escape(e, instruction_s3(iptr));
622 if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
623 escape_analysis_ensure_state(e, instruction_s3(iptr), ESCAPE_GLOBAL);
625 escape_analysis_ensure_state(e, instruction_s3(iptr), escape_analysis_get_state(e, instruction_s1(iptr)));
626 escape_analysis_add_dependency(e, iptr);
631 if (instruction_field_type(iptr) == TYPE_ADR) {
632 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
633 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
638 if (instruction_field_type(iptr) == TYPE_ADR) {
640 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
643 if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
644 /* Fields loaded from arguments escape globally.
647 => y escapes globally. */
648 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
650 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
653 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
655 instruction_list_add(e->getfields, iptr);
659 case ICMD_ARRAYLENGTH:
661 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
667 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
670 if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
671 /* If store into argument, escapes globally. See ICMD_GETFIELD. */
672 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
674 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
677 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
679 instruction_list_add(e->getfields, iptr);
685 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
686 escape_analysis_assert_has_escape(e, instruction_s2(iptr));
688 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
689 escape_analysis_ensure_state(e, instruction_s2(iptr), ESCAPE_METHOD);
696 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
698 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
703 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
705 escape_analysis_merge(e, instruction_s1(iptr), instruction_dst(iptr));
706 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
707 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
710 case ICMD_INSTANCEOF:
712 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
714 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
717 case ICMD_INVOKESPECIAL:
718 case ICMD_INVOKEVIRTUAL:
719 case ICMD_INVOKEINTERFACE:
720 case ICMD_INVOKESTATIC:
721 count = instruction_arg_count(iptr);
722 mi = instruction_local_methodinfo(iptr);
726 /* If the method could be resolved, it already is. */
727 paramescape = mi->paramescape;
729 if (paramescape == NULL) {
731 printf("BC escape analyzing callee.\n");
733 bc_escape_analysis_perform(mi);
734 paramescape = mi->paramescape;
738 printf("Unresolved callee.\n");
742 for (i = 0; i < count; ++i) {
743 if (instruction_arg_type(iptr, i) == TYPE_ADR) {
746 escape_analysis_assert_has_escape(e, instruction_arg(iptr, i));
748 if (paramescape == NULL) {
749 escape_analysis_ensure_state(
751 instruction_arg(iptr, i),
752 instruction_local_methodinfo(iptr) && instruction_local_methodinfo(iptr)->jcode ?
753 ESCAPE_GLOBAL_THROUGH_METHOD :
756 } else if ((escape_state_t)*paramescape < ESCAPE_METHOD) {
757 escape_analysis_ensure_state(e, instruction_arg(iptr, i), ESCAPE_METHOD);
759 escape_analysis_ensure_state(e, instruction_arg(iptr, i), (escape_state_t)*paramescape);
762 if (paramescape != NULL) {
768 if (instruction_return_type(iptr) == TYPE_ADR) {
769 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
770 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
777 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
779 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
784 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
786 escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
793 if (instruction_dst_type(iptr, jd) == TYPE_ADR) {
795 escape_analysis_assert_has_escape(e, instruction_s1(iptr));
797 escape_analysis_merge(e, instruction_s1(iptr), instruction_dst(iptr));
798 escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
804 iarg = iptr->sx.s23.s2.iargs;
805 iarg != iptr->sx.s23.s2.iargs + iptr->s1.argcount;
808 escape_analysis_merge(e, instruction_dst(iptr), instruction_dst(*iarg));
812 case ICMD_GETEXCEPTION:
813 escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
818 static void escape_analysis_process_instructions(escape_analysis_t *e) {
822 FOR_EACH_BASICBLOCK(e->jd, bptr) {
824 for (iptr = bptr->phis; iptr != bptr->phis + bptr->phicount; ++iptr) {
825 escape_analysis_process_instruction(e, iptr);
828 FOR_EACH_INSTRUCTION(bptr, iptr) {
829 escape_analysis_process_instruction(e, iptr);
835 static void escape_analysis_post_process_getfields(escape_analysis_t *e) {
836 instruction_list_item_t *iti;
837 dependency_list_item_t *itd;
839 dependency_list_t *dl;
841 FOR_EACH_INSTRUCTION_LIST(e->getfields, iti) {
845 /* Get the object the field/element is loaded from. */
847 dl = var_extra_get_dependency_list(e, instruction_s1(iptr));
849 /* Adjust escape state of all objects in the dependency list,
850 referenced via the field of this getfield/arraystore. */
853 FOR_EACH_DEPENDENCY_LIST(dl, itd) {
854 if (dependency_list_item_compare(itd, iptr)) {
856 /* Fields match. Adjust escape state. */
858 escape_analysis_ensure_state(
860 dependency_list_item_get_dependency(itd),
861 escape_analysis_get_state(e, instruction_dst(iptr))
870 static void display_allocation(escape_analysis_t *e, const char *prefix, const instruction *iptr, escape_state_t es) {
871 const char *cl = "WTF";
874 if (instruction_get_opcode(iptr) == ICMD_NEW) {
875 c = escape_analysis_classinfo_in_var(e, instruction_arg(iptr, 0));
883 " %s %s %s: %s %s @%d %s\n",
885 e->jd->m->clazz->name->text,
886 e->jd->m->name->text,
887 icmd_table[iptr->opc].name,
890 escape_state_to_string(es)
894 static void escape_analysis_mark_allocations(escape_analysis_t *e) {
895 instruction_list_item_t *iti;
898 FOR_EACH_INSTRUCTION_LIST(e->allocations, iti) {
899 es = escape_analysis_get_state(e, instruction_dst(iti->instr));
900 if (es < ESCAPE_GLOBAL_THROUGH_METHOD) {
901 display_allocation(e, "****", iti->instr, es);
903 if (es == ESCAPE_GLOBAL_THROUGH_METHOD) {
904 display_allocation(e, "!!!!", iti->instr, es);
910 static void escape_analysis_process_arguments(escape_analysis_t *e) {
917 md = e->jd->m->parseddesc;
919 for (p = 0, l = 0; p < md->paramcount; ++p) {
920 t = md->paramtypes[p].type;
921 varindex = e->jd->local_map[l * 5 + t];
923 if (varindex != UNUSED) {
924 escape_analysis_ensure_state(e, varindex, ESCAPE_NONE);
925 escape_analysis_set_is_argument(e, varindex);
927 e->adr_args_count += 1;
929 l += IS_2_WORD_TYPE(t) ? 2 : 1;
933 static void escape_analysis_export_arguments(escape_analysis_t *e) {
941 md = e->jd->m->parseddesc;
943 paramescape = MNEW(u1, e->adr_args_count);
944 e->jd->m->paramescape = paramescape;
946 for (p = 0, l = 0; p < md->paramcount; ++p) {
947 t = md->paramtypes[p].type;
948 varindex = e->jd->local_map[l * 5 + t];
950 if (varindex == UNUSED) {
951 *paramescape = (u1)ESCAPE_NONE;
953 *paramescape = (u1)escape_analysis_get_state(e, varindex);
956 printf("adr parameter %d: %s\n", p, escape_state_to_string((escape_state_t)*paramescape));
960 l += IS_2_WORD_TYPE(t) ? 2 : 1;
964 static void escape_analysis_display(escape_analysis_t *e) {
965 instruction_list_item_t *iti;
969 FOR_EACH_INSTRUCTION_LIST(e->allocations, iti) {
971 ve = var_extra_get(e, instruction_dst(iptr));
974 icmd_table[iptr->opc].name,
976 escape_state_to_string(ve->escape_state)
981 void escape_analysis_perform(jitdata *jd) {
982 escape_analysis_t *e;
984 jd->m->flags |= ACC_METHOD_EA;
986 /*bc_escape_analysis_perform(jd->m);*/
988 e = DNEW(escape_analysis_t);
989 escape_analysis_init(e, jd);
992 printf("==== %s/%s ====\n", e->jd->m->clazz->name->text, e->jd->m->name->text);
994 /*fprintf(stderr, ".");*/
996 escape_analysis_process_arguments(e);
997 escape_analysis_process_instructions(e);
998 escape_analysis_post_process_getfields(e);
999 escape_analysis_export_arguments(e);
1000 if (e->verbose) escape_analysis_display(e);
1001 escape_analysis_mark_allocations(e);
1003 jd->m->flags &= ~ACC_METHOD_EA;
1006 void escape_analysis_escape_check(void *vp) {