1 /* jit/parseRT.c - parser and print functions for Rapid Type Analyis
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Carolyn Oates
29 $Id: parseRT.c 1203 2004-06-22 23:14:55Z twisti $
32 opcode put into functions
33 changed class_findmethod class_fetchmethod
41 /*------------ global variables -----------------------------------------*/
42 #define MAXCALLGRAPH 5000
44 #include "parseRTflags.h"
47 bool NATIVE = false; // Dez version chasing Native problems
49 int callgraphAddedBy[MAXCALLGRAPH]; // add comment
53 int methRTmax = MAXCALLGRAPH;
54 methodinfo **callgraph;
55 /*methodinfo *callgraph[MAXCALLGRAPH];*/
60 int methXTAmax = MAXCALLGRAPH;
61 methodinfo **XTAcallgraph;
62 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
64 static bool nativecallcompdone=0 ;
66 static bool firstCall= true;
67 static bool parse1 = true;
68 static bool AfterMain = false;
69 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
70 /* so easier to build dynmanic calls file */
71 static FILE *appldynm; /* Methods dynamically loaded by application */
73 static utf *utf_OBJECT; /* utf_new_char("Object"); */
74 static utf *utf_MAIN; /* utf_new_char("main"); */
75 static utf *INIT ; /* utf_new_char("<init>"); */
76 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
77 static utf *FINALIZE; /* utf_new_char("finalize"); */
78 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
79 static int missedCnt = 0;
82 /*--------------------------------------------------------------*/
83 /* addToCallgraph - adds to RTA callgraph and */
84 /* sets meth->methodUsed to USED */
85 /*--------------------------------------------------------------*/
86 // if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) {
87 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
89 callgraph[++methRTlast] = meth ; \
90 meth->methodUsed = USED; \
92 {printf("\n Added to Call Graph #%i:", \
94 printf("\t <used flags c/m> <%i/%i> %i\t", \
95 meth->class->classUsed, \
98 printf(" method name ="); \
99 utf_display(meth->class->name);printf("."); \
100 method_display(meth);fflush(stdout);} \
103 /*--------------------------------------------------------------*/
104 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
107 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
108 if (subs->classUsed == USED) {
109 if (class_findmethod_w(class, meth->name, meth->descriptor,"rtaSubUsed") == NULL)
114 if (rtaSubUsed(subs, meth))
121 /*--------------------------------------------------------------*/
122 /* Mark the method with same name /descriptor in topmethod */
125 /* Class not marked USED and method defined in this class -> */
126 /* -> if Method NOTUSED mark method as MARKED */
127 /* Class marked USED and method defined in this class -> */
128 /* -> mark method as USED */
130 /* Class USED, but method not defined in this class -> */
131 /* -> search up the heirarchy and mark method where defined */
132 /* if class where method is defined is not USED -> */
133 /* -> mark class with defined method as PARTUSED */
134 /*--------------------------------------------------------------*/
136 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
138 utf *name = topmethod -> name;
139 utf *descriptor = topmethod -> descriptor;
142 submeth = class_resolvemethod(class, name, descriptor);
144 panic("parse RT: Method not found in class hierarchy");
145 if (submeth->methodUsed == USED) return;
147 if (submeth->class == class) {
149 /*--- Method defined in class -----------------------------*/
150 if (submeth->class->classUsed != USED) {
151 if (submeth->methodUsed == NOTUSED) {
153 /* Class NOT marked USED and method defined in this class -> */
154 /* -> if Method NOTUSED mark method as MARKED */
155 if (pWhenMarked >= 1) {
156 printf("MARKED class.method\t");
157 utf_display(submeth->class->name);printf(".");method_display(submeth);
159 if (rtaSubUsed(submeth->class,submeth)) {
160 submeth->class->classUsed = PARTUSED;
161 ADDTOCALLGRAPH(submeth)
164 submeth->methodUsed = MARKED;
169 /* Class IS marked USED and method defined in this class -> */
170 /* -> mark method as USED */
171 ADDTOCALLGRAPH(submeth)
173 } /* end defined in class */
176 /*--- Method NOT defined in class -----------------------------*/
177 if (submeth->class->classUsed == NOTUSED) {
178 submeth->class->classUsed = PARTUSED;
179 if (class->classUsed != USED) {
180 submeth->methodUsed = MARKED;
183 if ( (submeth->class->classUsed == USED)
184 || (class->classUsed == USED)) {
185 ADDTOCALLGRAPH(submeth)
187 } /* end NOT defined in class */
190 /*-------------------------------------------------------------------------------*/
191 /* Mark the method with the same name and descriptor as topmethod */
192 /* and any subclass where the method is defined and/or class is used */
194 /*-------------------------------------------------------------------------------*/
195 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
197 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
198 if (class->sub != NULL) {
201 if (!(topmethod->flags & ACC_FINAL )) {
202 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
204 rtaMarkSubs(subs, topmethod);
211 /*-------------------------------------------------------------------------------*/
212 /* Add Marked methods for input class ci */
213 /* Add methods with the same name and descriptor as implemented interfaces */
214 /* with the same method name */
216 /*-------------------------------------------------------------------------------*/
217 void rtaAddMarkedMethods(classinfo *ci) {
220 /* add marked methods to callgraph */
221 for (ii=0; ii<ci->methodscount; ii++) {
222 methodinfo *mi = &(ci->methods[ii]);
223 if (mi->methodUsed == MARKED) {
224 if (pWhenMarked >= 1) {
225 printf("ADDED a method that was MARKED\n");
230 // from Dez if (NATIVE == true) { printf("NOT MARKED: "); method_display(mi);}
232 for (jj=0; jj < ci -> interfacescount; jj++) {
233 classinfo *ici = ci -> interfaces [jj];
234 /* use resolve method....!!!! */
235 if (ici -> classUsed != NOTUSED) {
236 for (mm=0; mm< ici->methodscount; mm++) {
237 methodinfo *imi = &(ici->methods[mm]);
239 if ( (imi->methodUsed == USED)
240 && ( (imi->name == mi->name)
241 && (imi->descriptor == mi->descriptor))) {
242 if (pWhenMarked >= 1)
243 printf("ADDED a method that was used by an interface\n");
252 /*-------------------------------------------------------------------------------*/
254 /*-------------------------------------------------------------------------------*/
256 xtainfo *xtainfoInit(methodinfo *m)
260 m ->xta = (xtainfo *) NEW(xtainfo);
261 m ->xta-> XTAmethodUsed = NOTUSED;
262 m ->xta-> XTAclassSet = NULL;
263 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
266 m->xta->paramClassSet = NULL;
267 m->xta->calls = NULL;
268 m->xta->calledBy = NULL;
270 m->xta->marked = NULL; /* comment out*/
271 m ->xta->markedBy = NULL;
272 m->xta->fldsUsed = NULL;
273 /*m ->xta->interfaceCalls = NULL*/
274 m->xta->chgdSinceLastParse = false;
279 xtafldinfo * xtafldinfoInit (fieldinfo *f)
284 f->xta = NEW(xtafldinfo);
286 f->xta->fieldChecked = false; /*XTA*/
287 f->xta->fldClassType = NULL; /*XTA*/
288 f->xta->XTAclassSet = NULL; /*XTA*/
294 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
303 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
305 printf("\tIN SmCalled set : ");
306 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
307 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
309 printf("\tIN SmCalls set: ");
310 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
311 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
313 printf("\tIN lastptrInto : (");
314 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
315 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
317 else {printf("NULL) ");}
319 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
320 method_display(lastptrInto->methRef); fflush(stdout);
321 printf("\n");fflush(stdout);
324 /* Get SmCalled ParamType set if null */
325 if (SmCalled->xta->paramClassSet == NULL) {
326 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
329 printf("\tParamPassed\n"); fflush(stdout);
330 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
331 printf("\n"); fflush(stdout);
334 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
335 if (SmCalls->xta->XTAclassSet != NULL)
336 c1 = SmCalls->xta->XTAclassSet->head;
341 /* start with type where left off */
342 c1 = lastptrInto->lastptrIntoClassSet2;
343 c1 = c1 -> nextClass; /* even if NULL */
348 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
351 printf("\tIN SmCalls ... start with :");fflush(stdout);
352 utf_display(c1->classType->name); printf("\n");
356 /* for each Param Class */
357 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
359 /* for each SmCalls class */
360 for (c=c1; c != NULL; c = c->nextClass) {
361 vftbl *p_cl_vt = p->classType->vftbl;
362 vftbl *c_cl_vt = c->classType->vftbl;
364 /* if SmCalls class is in the Params Class range */
365 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
366 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
368 /* add SmCalls class to SmCalledBy Class set */
369 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
375 lastptrInto->lastptrIntoClassSet2 = cprev;
377 printf("\tOUT SmCalled set: ");fflush(stdout);
378 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
380 printf("\tOUT SmCalls set: ");fflush(stdout);
381 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
383 printf("\tOUT lastptrInto="); fflush(stdout);
384 if (lastptrInto->lastptrIntoClassSet2 != NULL)
385 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
387 printf("<rc=%i>\n",rc);fflush(stdout);
392 /*-------------------------------------------------------------------------------*/
393 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
400 printf("xtaPassReturnType \n");
402 /* Get SmCalled return class is null */
403 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
404 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
407 if (SmCalled->returnclass == NULL) {
409 printf("\tReturn type is NULL\n");
414 printf("\tReturn type is: ");
415 utf_display(SmCalled->returnclass->name);
418 printf("\tIN SmCalls set: ");
419 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
420 printClassSet(SmCalls->xta->XTAclassSet);
422 printf("\tIN SmCalled set: ");
423 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
424 printClassSet(SmCalled->xta->XTAclassSet);
428 if (SmCalled->xta->XTAclassSet == NULL)
431 cs1 = SmCalled->xta->XTAclassSet->head;
432 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
433 classinfo *c = cs->classType;
434 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
435 vftbl *c_cl_vt = c->vftbl;
437 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
438 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
439 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
440 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
446 printf("\tOUT SmCalls set: ");
447 printClassSet(SmCalls->xta->XTAclassSet);
452 /*-------------------------------------------------------------------------------*/
453 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
456 mi->xta = xtainfoInit(mi);
457 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
458 mi->xta->XTAmethodUsed = USED;
459 if (!(mi->flags & ACC_ABSTRACT)) {
460 if (mi->methodUsed != USED) {
461 XTAcallgraph[++methXTAlast] = mi;
462 mi->methodUsed = USED;
463 /*RTprint*/ if (pClassHeir >= 1) {
470 /*RTAprint*/ if(pWhenMarked>=1) {
471 /*RTAprint*/ printf("\nxxxxxxxxxxxxxxxxx XTA set Used or Added to Call Graph #%i:",
472 /*RTAprint*/ methXTAlast);
473 /*RTAprint*/ printf(" method name ="); fflush(stdout);
474 /*RTAprint*/ utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
475 /*RTAprint*/ method_display(mi);fflush(stdout);
476 /*RTAprint*/ printf("\t\t\t\tcalledBy:");
477 /*RTAprint*/ utf_display(rt_method->class->name);fflush(stdout); printf(".");fflush(stdout);
478 /*RTAprint*/ method_display(rt_method);fflush(stdout);
481 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
482 rt_method->xta->calls->tail->monoPoly = monoPoly;
483 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
484 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
485 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
489 /*--------------------------------------------------------------*/
490 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
493 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
495 if (inSet(subtypesUsedSet,subs)) {
496 if (class_findmethod_w(class, meth->name, meth->descriptor, "xtaSubUsed") == NULL)
499 if (class_findmethod_w(subs, meth->name, meth->descriptor, "xtaSubUsed") == NULL)
503 if (xtaSubUsed(subs, meth, subtypesUsedSet))
510 /*-------------------------------------------------------------------------------*/
511 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
515 utf *name = topmethod -> name;
516 utf *descriptor = topmethod -> descriptor;
518 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
519 method_display(topmethod);
522 submeth = class_resolvemethod(class, name, descriptor);
525 printf(" def: "); utf_display(submeth->class->name); printf("\n");fflush(stdout);
530 panic("parse XTA: Method not found in class hierarchy");
531 if (submeth->xta == NULL)
532 submeth->xta = xtainfoInit(submeth);
534 if (rt_method->xta->calls != NULL) {
535 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
538 if (submeth->class == class) {
540 /*--- Method defined in class -----------------------------*/
541 if (inSet(subtypesUsedSet,submeth->class)) {
542 xtaAddCallEdges(submeth,POLY);
545 if (subtypesUsedSet != NULL) {
546 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
547 xtaAddCallEdges(submeth,POLY);
550 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
552 printf("\t(defd) Added to MarkBy Set\n"); fflush(stdout);
553 utf_display(submeth->class->name); printf("."); fflush(stdout);
554 method_display(submeth);
555 printMethodSet(submeth->xta->markedBy);
562 /*--- Method NOT defined in class -----------------------------*/
563 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
564 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
565 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
566 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
568 printf("\t(^^defd) Added to MarkBy Set\n"); fflush(stdout);
569 utf_display(submeth->class->name); printf("."); fflush(stdout);
570 method_display(submeth);
571 printMethodSet(submeth->xta->markedBy);
575 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
576 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
577 xtaAddCallEdges(submeth,POLY);
580 } /* end defined in class */
583 /*-------------------------------------------------------------------------------*/
584 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
585 /* xtaPRINTmarkSubs1*/
586 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
587 if (class->sub != NULL) {
590 if (!(topmethod->flags & ACC_FINAL )) {
591 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
592 /* xtaPRINTmarkSubs1 */
593 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
599 /*-------------------------------------------------------------------------------*/
600 /* Add Marked methods for input class ci */
601 /* Add methods with the same name and descriptor as implemented interfaces */
602 /* with the same method name */
604 /*-------------------------------------------------------------------------------*/
605 void xtaAddMarkedMethods(classinfo *ci) {
608 /* add marked methods to callgraph */
609 for (ii=0; ii<ci->methodscount; ii++) {
610 methodinfo *mi = &(ci->methods[ii]);
611 if (mi->xta != NULL) {
612 if (mi->xta->markedBy != NULL) {
614 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
615 methodinfo *mc = mcnode->methRef;
616 if (pWhenMarked >= 1) {
617 printf("ADDED a method that was MARKED\n");
619 xtaAddCallEdges(mi,POLY);
623 for (jj=0; jj < ci -> interfacescount; jj++) {
624 classinfo *ici = ci -> interfaces [jj];
625 /* use resolve method....!!!! */
626 if (ici -> classUsed != NOTUSED) {
627 for (mm=0; mm< ici->methodscount; mm++) {
628 methodinfo *imi = &(ici->methods[mm]);
629 if (imi->xta != NULL) {
630 if ((imi->xta->XTAmethodUsed == USED)
631 && ( (imi->name == mi->name)
632 && (imi->descriptor == mi->descriptor))) {
633 if (pWhenMarked >= 1)
634 printf("ADDED a method that was used by an interface\n");
635 xtaAddCallEdges(mi,POLY);
646 /*-------------------------------------------------------------------------------*/
647 /* Both RTA and XTA */
648 /*-------------------------------------------------------------------------------*/
650 int addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark) {
651 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
654 utf* utf_java_lang_system = utf_new_char("java/lang/System");
655 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
656 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
658 int m, m1=-1, m2=-1, mf=-1;
661 if (clinits) { /* No <clinit> available - ignore */
663 /* Get clinit methodinfo ptr */
664 if ((mi = class_resolvemethod(ci,CLINIT, EMPTY_DESC)) !=NULL) {
665 if (mi->class != ci) {
666 printf("WARNING:::::<clinit> method not found in class requested: ");
667 utf_display(ci->name); printf(" found in:"); utf_display(mi->class->name);
671 if ( mi->methodUsed != USED) {
672 mi->class->classUsed = PARTUSED;
677 if ((XTAOPTbypass) || (opt_xta)) {
678 xtaAddCallEdges(mi,MONO);
682 printf("class=");utf_display(ci->name);
684 if (ci->super != NULL)
685 utf_display(ci->super->name);
688 if ( (ci->super->name != utf_OBJECT) && (ci->name != utf_OBJECT) )
689 panic("<clinit> method not found");
695 /* Get finalize methodinfo ptr */
696 if ( (mi = class_findmethod (ci,FINALIZE, EMPTY_DESC)) != NULL) {
698 if ( mi->methodUsed != USED) {
699 mi->class->classUsed = PARTUSED;
704 if ((XTAOPTbypass) || (opt_xta)) {
705 xtaAddCallEdges(mi,MONO);
710 /*Special Case for System class init:
711 add java/lang/initializeSystemClass to callgraph */
713 /* if (class->name == utf_initializeSystemClass) { */
714 if (mi->class->name == utf_initializeSystemClass) {
715 /* Get clinit methodinfo ptr */
716 if ((mi = class_findmethod (ci,utf_initializeSystemClass, EMPTY_DESC)) != NULL) {
718 if ( mi->methodUsed != USED) {
719 mi->class->classUsed = PARTUSED;
724 if ((XTAOPTbypass) || (opt_xta)) {
725 xtaAddCallEdges(mi,MONO);
730 /* add marked methods to callgraph */
731 if ((XTAOPTbypass) || (opt_xta))
732 xtaAddMarkedMethods(ci);
734 rtaAddMarkedMethods(ci);
741 #define rt_code_get_u1(p) rt_jcode[p]
742 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
743 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
744 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
745 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
746 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
747 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
748 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
752 /*-------------------------------------------------------------------------------*/
753 void rtaAddUsedInterfaceMethods(classinfo *ci) {
756 /* add used interfaces methods to callgraph */
757 for (jj=0; jj < ci -> interfacescount; jj++) {
758 classinfo *ici = ci -> interfaces [jj];
760 if (pWhenMarked >= 1) {
761 printf("BInterface used: ");fflush(stdout);
762 utf_display(ici->name);
763 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
764 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
765 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
766 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
769 /* add class to interfaces list of classes that implement it */
770 ici -> impldBy = addElement(ici -> impldBy, ci);
772 /* if interface class is used */
773 if (ici -> classUsed != NOTUSED) {
775 /* for each interface method implementation that has already been used */
776 for (mm=0; mm< ici->methodscount; mm++) {
777 methodinfo *imi = &(ici->methods[mm]);
778 if (pWhenMarked >= 1) {
779 if (imi->methodUsed != USED) {
780 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
781 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
782 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
785 if (imi->methodUsed == USED) {
786 if (pWhenMarked >= 1) {
787 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
789 /* Mark this method used in the (used) implementing class and its subclasses */
790 printf("rMAY ADD methods that was used by an interface\n");
799 /*-------------------------------------------------------------------------------*/
800 void rtaMarkInterfaceSubs(methodinfo *mi) {
802 if (mi->class->classUsed == NOTUSED) {
803 mi->class->classUsed = USED;
804 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
807 /* add interface class to list kept in Object */
808 mi->methodUsed = USED;
811 subs = mi->class->impldBy;
812 RTAPRINT08invokeInterface1
813 while (subs != NULL) {
814 classinfo * isubs = subs->classType;
815 RTAPRINT09invokeInterface2
816 /* Mark method (mark/used) in classes that implement the method */
817 if (isubs->classUsed != NOTUSED) {
820 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
822 submeth->monoPoly = POLY; /* poly even if nosubs */
823 rtaMarkSubs(isubs, mi);
826 subs = subs->nextClass;
830 /*-------------------------------------------------------------------------------*/
831 /*-------------------------------------------------------------------------------*/
835 /*-------------------------------------------------------------------------------*/
836 void xtaAddUsedInterfaceMethods(classinfo *ci) {
839 /* add used interfaces methods to callgraph */
840 for (jj=0; jj < ci -> interfacescount; jj++) {
841 classinfo *ici = ci -> interfaces [jj];
843 if (pWhenMarked >= 1) {
844 printf("XInterface used: ");fflush(stdout);
845 utf_display(ici->name);
846 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
847 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
848 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
849 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
852 /* add class to interfaces list of classes that implement it */
853 ici -> impldBy = addElement(ici -> impldBy, ci);
855 /* if interface class is used */
856 if (ici -> classUsed != NOTUSED) {
858 /* for each interface method implementation that has already been used */
859 for (mm=0; mm< ici->methodscount; mm++) {
860 methodinfo *imi = &(ici->methods[mm]); /*interface method */
861 printf("==%i==%i\n",ici->methodscount,mm);
862 if (imi->xta == NULL)
864 /*RTAprint*/if (pWhenMarked >= 1) {
865 /*RTAprint*/ if (imi->xta->XTAmethodUsed != USED) {
866 /*RTAprint*/ if (imi->xta->XTAmethodUsed==NOTUSED)
867 printf("Interface Method notused: ");
868 /*RTAprint*/ if (imi->xta->XTAmethodUsed==MARKED)
869 printf("Interface Method marked: ");
870 /*RTAprint*/ utf_display(ici->name);printf(".");
871 /*RTAprint*/ method_display(imi);fflush(stdout);
874 if (imi->xta->XTAmethodUsed == USED) {
875 methSetNode *mCalledBy = NULL;
876 if (pWhenMarked >= 1) {
877 printf("Interface Method used: "); utf_display(ici->name);printf(".");
878 method_display(imi);fflush(stdout);
880 /* Mark this method used in the (used) implementing class &its subclasses */
881 printf("xMAY ADD methods that was used by an interface\n"); fflush(stdout);
883 if (pWhenMarked >= 1) {
884 printf("calledBy set ="); fflush(stdout);
885 printMethodSet(imi->xta->calledBy);
887 if (imi->xta->calledBy != NULL) {
888 /* for each calledBy method */
889 for ( mCalledBy = imi->xta->calledBy->head;
891 mCalledBy = mCalledBy->nextmethRef) {
892 if (pWhenMarked >= 1) {
893 printf("xtaMarkSubs(");
894 utf_display(ci->name); printf("."); fflush(stdout);
896 printf("mCalledBy method class set BEFORE\n"); fflush(stdout);
897 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
899 xtaMarkSubs(ci,imi,mCalledBy->methRef->xta->XTAclassSet->head);
900 if (pWhenMarked >= 1) {
901 printf("mCalledBy method class set AFTER \n"); fflush(stdout);
902 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
912 /*-------------------------------------------------------------------------------*/
914 /*-------------------------------------------------------------------------------*/
915 void xtaMarkInterfaceSubs(methodinfo *mi) {
922 if (mi->class->classUsed != USED) {
923 mi->class->classUsed = USED;
924 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
927 /* add interface class to list kept in Object */
928 if (pWhenMarked >= 1) {
929 printf("Marking Interface Method: "); fflush(stdout);
931 xtaAddCallEdges(mi,POLY);
933 subs = mi->class->impldBy;
934 RTAPRINT08invokeInterface1
935 while (subs != NULL) {
936 classinfo * isubs = subs->classType;
937 RTAPRINT09invokeInterface2
938 /* Mark method (mark/used) in classes that implement the method */
939 if (isubs->classUsed != NOTUSED) {
942 submeth = class_resolvemethod(isubs,mi->name, mi->descriptor);
943 if (submeth != NULL) ///+1
945 classSetNode *subtypesUsedSet = NULL;
946 submeth->monoPoly = POLY; /* poly even if nosubs */
948 mi->xta->XTAmethodUsed = USED;
949 if (rt_method->xta->XTAclassSet != NULL)
951 intersectSubtypesWithSet
952 (subs->classType, rt_method->xta->XTAclassSet->head);
954 if (pWhenMarked >= 1) {
955 /*RTAprint*/ printf(" \nXTA subtypesUsedSet: ");
956 /*RTAprint*/ fflush(stdout);
957 /*RTAprint*/ printSet(subtypesUsedSet);
959 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
962 subs = subs->nextClass;
965 /*-------------------------------------------------------------------------------*/
967 /*-------------------------------------------------------------------------------*/
968 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
972 if (fi->xta->fieldChecked) {
973 if (fi->xta->fldClassType != NULL)
974 return true; /* field has a class type */
978 fi->xta->fieldChecked = true;
980 if (fi->type == TYPE_ADDRESS) {
981 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
983 if (*utf_ptr != 'L') {
984 while (*utf_ptr++ =='[') ;
987 if (*utf_ptr =='L') {
989 if (fi->xta->fldClassType== NULL) {
994 desc = MNEW(char, 256);
995 strcpy(desc,++utf_ptr);
996 cname = strtok(desc,";");
998 printf("STATIC fields type is: %s\n",cname);
1001 class = class_get(utf_new_char(cname));
1002 fi->xta->fldClassType= class; /* save field's type class ptr */
1009 /*-------------------------------------------------------------------------------*/
1010 void xtaPassFldPUT(fldSetNode *fN)
1012 /* Field type is a class */
1014 classSetNode *c1 = NULL;
1015 classSetNode *cp = NULL;
1016 classSetNode *cprev= NULL;
1024 /* Use lastptr so don't check whole XTA class set each time */
1025 cp = fN->lastptrPUT;
1027 if (cp->nextClass != NULL)
1028 c1 = cp -> nextClass;
1031 if (rt_method->xta->XTAclassSet != NULL)
1032 c1 = rt_method->xta->XTAclassSet->head;
1035 printf("rt XTA class set =");fflush(stdout);
1036 printClassSet(rt_method->xta->XTAclassSet);
1037 printf("\t\tField class type = ");fflush(stdout);
1038 utf_display(fi->xta->fldClassType->name); printf("\n");
1042 /*--- PUTSTATIC specific ---*/
1043 /* Sx = intersection of type+subtypes(field x) */
1044 /* and Sm (where putstatic code is) */
1045 for (c=c1; c != NULL; c=c->nextClass) {
1046 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
1047 vftbl *c_cl_vt = c-> classType->vftbl;
1049 printf("\tXTA class = ");fflush(stdout);
1050 utf_display(c->classType->name);
1051 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
1052 if (c->nextClass == NULL) {
1053 printf("next=NULL ");fflush(stdout);
1056 printf("next="); fflush(stdout);
1057 utf_display(c->nextClass->classType->name);
1058 printf("\n"); fflush(stdout);
1061 printf("\t\tField class type = ");fflush(stdout);
1062 utf_display(fi->xta->fldClassType->name);
1063 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
1066 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
1067 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
1068 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
1072 fN->lastptrPUT = cprev;
1074 /*-------------------------------------------------------------------------------*/
1075 void xtaPassFldGET(fldSetNode *fN)
1077 /* Field type is a class */
1079 classSetNode *c1 = NULL;
1080 classSetNode *cp = NULL;
1081 classSetNode *cprev= NULL;
1089 /* Use lastptr so don't check whole XTA class set each time */
1090 cp = fN->lastptrGET;
1092 if (cp->nextClass != NULL)
1093 c1 = cp -> nextClass;
1096 if (fi->xta->XTAclassSet != NULL)
1097 c1 = fi->xta->XTAclassSet->head;
1100 printf("fld XTA class set =");fflush(stdout);
1101 printClassSet(fi->xta->XTAclassSet);
1102 printf("\t\tField class type = ");fflush(stdout);
1103 utf_display(fi->xta->fldClassType->name); printf("\n");
1107 /*--- GETSTATIC specific ---*/
1108 /* Sm = union of Sm and Sx */
1109 for (c=c1; c != NULL; c=c->nextClass) {
1110 bool addFlg = false;
1111 if (rt_method->xta->XTAclassSet ==NULL)
1114 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
1118 rt_method->xta->XTAclassSet
1119 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
1124 fN->lastptrGET = cprev;
1128 /*-------------------------------------------------------------------------------*/
1129 void xtaPassAllCalledByParams () {
1130 methSetNode *SmCalled;
1132 if (XTAdebug >= 1) {
1133 printf("xta->calledBy method set: "); fflush(stdout);
1135 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
1136 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
1138 if (rt_method->xta->calledBy == NULL)
1141 s1 = rt_method->xta->calledBy->head;
1142 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1143 if (XTAdebug >= 1) {
1144 printf("SmCalled = "); fflush(stdout);
1145 utf_display(SmCalled->methRef->class->name); fflush(stdout);
1146 printf(".");fflush(stdout); method_display(SmCalled->methRef);
1149 rt_method->xta->chgdSinceLastParse = false;
1150 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
1154 /*-------------------------------------------------------------------------------*/
1155 void xtaAllFldsUsed ( ){
1157 fldSetNode *f1=NULL;
1158 /* bool chgd = false */
1160 if (rt_method->xta->fldsUsed == NULL) return;
1162 /* for each field that this method uses */
1163 f1 = rt_method->xta->fldsUsed->head;
1165 for (f=f1; f != NULL; f = f->nextfldRef) {
1173 /*-------------------------------------------------------------------------------*/
1174 void xtaMethodCalls_and_sendReturnType()
1176 methSetNode *SmCalled; /* for return type */
1177 methSetNode *SmCalls; /* for calls param types */
1178 methSetNode *s1=NULL;
1180 if (XTAdebug >= 1) {
1181 printf("calls method set Return type: ");
1182 printMethodSet(rt_method->xta->calls);
1186 /* for each method that this method calls */
1187 if (rt_method->xta->calls == NULL)
1190 s1 = SmCalls=rt_method->xta->calls->head;
1192 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
1193 /* pass param types */
1195 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
1196 /* if true chgd after its own parse */
1197 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
1198 SmCalls->methRef->xta->chgdSinceLastParse = true;
1202 /* for each calledBy method */
1203 /* send return type */
1204 if (rt_method->xta->calledBy == NULL)
1207 s1 = rt_method->xta->calledBy->head;
1208 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1210 if (XTAdebug >= 1) {
1211 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
1212 printf("."); method_display(SmCalled->methRef);
1215 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
1216 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1217 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
1222 /*-------------------------------------------------------------------------------*/
1223 /* -- Processes STATIC & PRIVATE methods
1225 * -- called for INVOKESTATIC, INVOKESPECIAL - PRIVATE and
1226 * STATIC / PRIVATE methods used by NATIVE methods
1227 *-------------------------------------------------------------------------------*/
1229 // Dez Version but gives too many Missed
1230 void invokestatic2( methodinfo *mi) {
1232 mi->class->classUsed = PARTUSED;
1234 addClassInit(mi->class, true, true, true);
1235 RTAPRINT04invokestatic1
1242 if ((XTAOPTbypass) || (opt_xta)) {
1243 mi->class->classUsed = PARTUSED;
1244 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,mi->class);
1245 xtaAddCallEdges(mi,MONO);
1251 //// from just RTA version before Dez changes
1252 void invokestatic(methodinfo *mi){
1253 RTAPRINT04invokestatic1
1254 if (mi->class->classUsed == NOTUSED) {
1255 mi->class->classUsed = USED;
1256 RTAPRINT05invokestatic2
1258 addClassInit(mi->class,true, true, true);
1264 if ((XTAOPTbypass) || (opt_xta)) {
1265 xtaAddCallEdges(mi,MONO);
1270 /*-------------------------------------------------------------------------------*/
1271 /* -- Processes <INIT> methods
1273 * -- called for INVOKESPECIAL - <init> and
1274 * <init> methods used by NATIVE methods
1275 *-------------------------------------------------------------------------------*/
1277 void initMethods(methodinfo *mi) {
1279 classinfo *ci = mi->class;
1281 /* new class so add marked methods */
1283 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1284 /*--- process NORMAL <init> method ---------------------------------------------*/
1285 if ( mi->methodUsed != USED) {
1287 - mark class as USED and <init> to callgraph */
1290 // addClassInit(mi->class,true, true, false);
1291 ci->classUsed = USED;
1292 rtaAddMarkedMethods(ci); /* add to callgraph marked methods */
1293 RTAPRINT06Binvoke_spec_init
1294 rtaAddUsedInterfaceMethods(ci);
1301 if ((XTAOPTbypass) || (opt_xta)) {
1302 if (mi->xta == NULL) {
1303 mi->xta = xtainfoInit(mi);
1305 if ((mi->xta->XTAmethodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1306 ci->classUsed = USED;
1307 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1308 xtaAddMarkedMethods(ci); /* add to callgraph marked methods */
1309 xtaAddUsedInterfaceMethods(ci);
1310 xtaAddCallEdges(mi,MONO);
1311 RTAPRINT06CXTAinvoke_spec_init1
1316 /*-------------------------------------------------------------------------------*/
1317 /* -- Processes VIRTUAL methods
1319 * -- called for INVOKEVIRTUAL and
1320 * virtual methods used by NATIVE methods
1321 *-------------------------------------------------------------------------------*/
1323 void invokevirtual(methodinfo *mi) {
1326 RTAPRINT07invoke_spec_virt2
1327 mi->class->classUsed = USED; // Should this be later?
1329 if ((mi->flags & ACC_STATIC) || (mi->flags & ACC_PRIVATE) || (mi->flags & ACC_FINAL) ) {
1335 mi->monoPoly = POLY;
1338 rtaMarkSubs(mi->class,mi);
1342 if ((XTAOPTbypass) || (opt_xta)) {
1343 classSetNode *subtypesUsedSet = NULL;
1344 if (rt_method->xta->XTAclassSet != NULL)
1346 intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1348 subtypesUsedSet = addElement(subtypesUsedSet, rt_method->class);
1350 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1351 printSet(subtypesUsedSet);
1353 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1358 /*-------------------------------------------------------------------------------*/
1359 void invokeinterface( methodinfo *mi ) {
1360 /*RTAprint*/ if (pWhenMarked >= 1) {
1361 /*RTAprint*/ printf("\t");fflush(stdout);
1362 /*RTAprint*/ utf_display(mi->class->name); printf(".");fflush(stdout);
1363 /*RTAprint*/ method_display(mi); fflush(stdout);
1366 if (mi->flags & ACC_STATIC)
1367 panic ("Static/Nonstatic mismatch calling static method");
1368 RTAPRINT08AinvokeInterface0
1371 rtaMarkInterfaceSubs(mi);
1374 if ((XTAOPTbypass2) || (opt_xta)) {
1375 xtaMarkInterfaceSubs(mi);
1379 /*-------------------------------------------------------------------------------*/
1380 void newClasses(classinfo *ci) {
1381 if (pWhenMarked >= 1) {
1382 printf("\tclass=");fflush(stdout);
1383 utf_display(ci->name); fflush(stdout);
1384 printf("=\n");fflush(stdout);
1387 if (ci->classUsed != USED) {
1389 ci->classUsed = USED; /* add to heirarchy */
1390 /* Add this class to the implemented by list of the abstract interface */
1391 rtaAddUsedInterfaceMethods(ci);
1392 addClassInit(ci, true, true, false);
1395 if ((XTAOPTbypass) || (opt_xta))
1397 xtaAddUsedInterfaceMethods(ci);
1398 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1403 /*-------------------------------------------------------------------------------*/
1404 static void parseRT(methodinfo *m)
1406 int p; /* java instruction counter */
1407 int nextp; /* start of next java instruction */
1408 int opcode; /* java opcode */
1409 int i; /* temporary for different uses (counters) */
1410 bool iswide = false; /* true if last instruction was a wide */
1414 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1415 printf("XTA parseRT():"); fflush(stdout);
1416 method_display(rt_method);
1417 if (rt_method->xta == NULL)
1418 xtainfoInit (rt_method);
1419 xtaPassAllCalledByParams ();
1420 printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1424 /* scan all java instructions */
1426 for (p = 0; p < rt_jcodelength; p = nextp) {
1427 opcode = rt_code_get_u1 (p); /* fetch op code */
1430 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
1433 /*--------------------------------*/
1434 /* Code just to get the correct next instruction */
1473 /* wider index for loading, storing and incrementing */
1487 /* table jumps ********************************/
1489 case JAVA_LOOKUPSWITCH:
1492 nextp = ALIGN((p + 1), 4);
1493 num = rt_code_get_u4(nextp + 4);
1494 nextp = nextp + 8 + 8 * num;
1499 case JAVA_TABLESWITCH:
1502 nextp = ALIGN ((p + 1),4);
1503 num = rt_code_get_s4(nextp + 4);
1504 num = rt_code_get_s4(nextp + 8) - num;
1505 nextp = nextp + 16 + 4 * num;
1509 /*-------------------------------*/
1510 case JAVA_PUTSTATIC:
1511 i = rt_code_get_u2(p + 1);
1513 constant_FMIref *fr;
1516 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1517 /* descr has type of field ref'd */
1518 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1519 RTAPRINT03putstatic1
1522 /* class with field - marked in addClassinit */
1523 addClassInit(fr->class, true, true, false);
1526 if ((XTAOPTbypass) || (opt_xta))
1528 if (fi->xta == NULL)
1529 fi->xta = xtafldinfoInit(fi);
1530 if (xtaAddFldClassTypeInfo(fi)) {
1531 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1537 case JAVA_GETSTATIC:
1538 i = rt_code_get_u2(p + 1);
1540 constant_FMIref *fr;
1543 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1544 /* descr has type of field ref'd */
1545 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1546 RTAPRINT03putstatic1
1549 /* class with field - marked in addClassinit */
1550 addClassInit(fr->class,true, true, true);
1553 if ((XTAOPTbypass) || (opt_xta) )
1555 if (fi->xta == NULL)
1556 fi->xta = xtafldinfoInit(fi);
1557 if (xtaAddFldClassTypeInfo(fi)) {
1558 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1566 /*-------------------- method invocation ---------------------*/
1568 case JAVA_INVOKESTATIC:
1569 i = rt_code_get_u2(p + 1);
1571 constant_FMIref *mr;
1574 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1575 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1577 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1583 case JAVA_INVOKESPECIAL:
1584 i = rt_code_get_u2(p + 1);
1586 constant_FMIref *mr;
1589 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1590 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1592 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1593 RTAPRINT06invoke_spec_virt1
1594 /*--- PRIVATE Method -----------------------------------------------------*/
1595 if (mi->name != INIT) { /* if method called is PRIVATE */
1596 RTAPRINT07invoke_spec_virt2
1597 RTAPRINT04invokestatic1
1602 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1609 case JAVA_INVOKEVIRTUAL:
1610 i = rt_code_get_u2(p + 1);
1612 constant_FMIref *mr;
1615 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1616 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1618 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1624 case JAVA_INVOKEINTERFACE:
1625 i = rt_code_get_u2(p + 1);
1627 constant_FMIref *mr;
1630 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1631 mi = class_resolveinterfacemethod (mr->class, mr->name, mr->descriptor, m->class, true);
1633 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1634 invokeinterface(mi);
1638 /* miscellaneous object operations *******/
1641 i = rt_code_get_u2 (p+1);
1645 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1658 if (p != rt_jcodelength)
1659 panic("Command-sequence crosses code-boundary");
1661 if ((XTAOPTbypass) || (opt_xta))
1662 xtaMethodCalls_and_sendReturnType();
1667 /*-------------------------------------------------------------------------------*/
1668 /* RTA add Native Methods/ Class functions */
1669 /*-------------------------------------------------------------------------------*/
1670 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1675 class = class_get(c1);
1676 if (class == NULL) {
1678 printf(" WARNING: CLASS used by NATIVE method is NULL so loaded\n");
1679 /* loader_load_sysclass(NULL, c1); */
1680 /* class = class_get(c1); */
1681 class = class_new(c1);
1682 if (class == NULL) {
1683 panic("CLASS used by NATIVE method is NULL and loading didn't help\n");
1684 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1688 if (class->classUsed == NOTUSED) {
1689 printf("NATIVE_MARKED CLASS USED "); utf_display(class->name); printf("\n");
1690 class->classUsed = USED; /* MARK CLASS USED */
1691 /* add marked methods to callgraph */
1692 rtaAddMarkedMethods(class);
1695 meth = class_findmethod_w (class, m1, d1,"findMarkNativeUsedMeth");
1697 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1698 panic("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1701 rtaMarkSubs(class,meth);
1704 /*-------------------------------------------------------------------------------*/
1706 void findMarkNativeUsedClass (utf * c) {
1709 class = class_get(c);
1710 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1711 class->classUsed = USED;
1713 /* add marked methods to callgraph */
1714 rtaAddMarkedMethods(class);
1718 /*-------------------------------------------------------------------------------*/
1720 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1724 nativecallcompdone = natcall2utf(nativecallcompdone);
1726 for (i=0; i<NATIVECALLSSIZE; i++) {
1727 if (rt_class == nativeCompCalls[i].classname) {
1729 /* find native class.method invoked */
1730 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1732 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1733 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1736 printf("#%i#\n",nativeCompCalls[i].callCnt[j]);
1737 /* mark methods and classes used by this native class.method */
1738 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1739 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1740 /* mark method used */
1741 findMarkNativeUsedMeth(
1742 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1743 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1744 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1747 printf("\nmark method used: "); fflush(stdout);
1748 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1749 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1750 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1754 /* mark class used */
1755 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1770 /*-------------------------------------------------------------------------------*/
1771 /*-------------------------------------------------------------------------------*/
1772 /* still need to look at field sets in 2nd pass and clinit ..... */
1773 void XTA_jit_parse2(methodinfo *m)
1775 int methRT; /* local */
1777 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1779 /* for each method in XTA worklist = callgraph (use RTA for now) */
1781 //while (methRT <= methRTlast) {
1782 while (methRT <= methXTAlast) {
1783 rt_method = XTAcallgraph[methRT];
1784 rt_class = rt_method->class;
1785 rt_descriptor = rt_method->descriptor;
1786 rt_jcodelength = rt_method->jcodelength;
1787 rt_jcode = rt_method->jcode;
1789 if (! ( (rt_method->flags & ACC_NATIVE )
1790 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1791 if (XTAdebug >= 1) {
1792 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1793 utf_display(rt_class->name); printf("."); fflush(stdout);
1794 method_display(rt_method);
1796 /* if XTA type set changed since last parse */
1797 if (rt_method->xta->chgdSinceLastParse) {
1799 /* get types from methods it is calledBy */
1800 xtaPassAllCalledByParams ();
1802 /* Pass parameter types to methods it calls and send the return type those called by */
1803 xtaMethodCalls_and_sendReturnType();
1808 if (XTAdebug >= 1) {
1810 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1811 printXTACallgraph ();
1814 RTAPRINT14CallgraphLast /*was >=2 */
1815 RTAPRINT15HeirarchyiLast /*was >= 2 */
1819 /*-------------------------------------------------------------------------------*/
1820 /*-------------------------------------------------------------------------------*/
1821 void mainRTAparseInit (methodinfo *m )
1823 /*printf("MAIN_NOT_STARTED \n");*/
1824 if (class_java_lang_Object->sub != NULL) {
1831 /* Frequently used utf strings */
1832 utf_OBJECT = utf_new_char("java/lang/Object");
1833 utf_MAIN = utf_new_char("main");
1834 INIT = utf_new_char("<init>");
1835 CLINIT = utf_new_char("<clinit>");
1836 FINALIZE = utf_new_char("finalize");
1837 EMPTY_DESC= utf_new_char("()V");
1839 /* open file for list of methods parsed before main method or missed and parsed after main */
1840 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1841 printf("CACAO - rtMissed file: cant open file to write\n");
1844 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1846 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1847 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1851 /* Allocate callgraph */
1853 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1855 if ((XTAOPTbypass) || (opt_xta)) {
1856 printf("XTAXTA CALLGRAPHS allocated\n");
1857 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1861 if (m->name == utf_MAIN) {
1862 rtMissed = fopen("rtMissed","a");
1863 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1868 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1869 printf("CACAO - rtMissed file: cant open file to write\n");
1872 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1873 utf_fprint(rtMissed,m->class->name);
1874 fprintf(rtMissed," ");
1875 fprintflags(rtMissed,m->flags);
1876 fprintf(rtMissed," ");
1877 utf_fprint(rtMissed,m->name);
1878 fprintf(rtMissed," ");
1879 utf_fprint(rtMissed,m->descriptor);
1880 fprintf(rtMissed,"\n");
1885 printf("#%i : ",methRT);
1886 printf("Method missed by static analysis Main parse. See ./rtMissed file\n");
1887 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1891 /* At moment start RTA before main when parsed */
1892 /* Will definitely use flag with to know if ok to apply in-lining. */
1896 /*-------------------------------------------------------------------------------*/
1897 /*-------------------------------------------------------------------------------*/
1899 void RTparseCGWorklist (methodinfo *m) {
1900 printf("IIIIIIIIIIIIIIIIIIIIn RTparseCGWorklist\n"); fflush(stdout);
1901 if (m->methodUsed == USED) return;
1902 if ((firstCall) || (parse1) || (m->name == utf_MAIN))
1903 mainRTAparseInit (m);
1905 m->methodUsed = USED;
1907 /* initialise parameter type descriptor */
1908 callgraph[++methRTlast] = m; /*-- RTA --*/
1909 RTAPRINT11addedtoCallgraph
1910 /* <init> then like a new class so add marked methods to callgraph */
1911 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1914 ci->classUsed = USED;
1915 if (pWhenMarked >= 1) {
1916 printf("Class=");utf_display(ci->name);
1918 /* add marked methods to callgraph */
1919 RTAPRINT11addedtoCallgraph2
1920 rtaAddMarkedMethods(ci);
1923 /*---- RTA call graph worklist -----***/
1924 while (methRT <= methRTlast) {
1925 rt_method = callgraph[methRT];
1926 rt_class = rt_method->class;
1927 rt_descriptor = rt_method->descriptor;
1928 rt_jcodelength = rt_method->jcodelength;
1929 rt_jcode = rt_method->jcode;
1931 if (! ( (rt_method->flags & ACC_NATIVE )
1932 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1935 //if (true == false) { // At moment nativecalls.h is not current and neither helps nor hinders
1937 RTAPRINT12bAbstractNative
1938 if (rt_method->flags & ACC_NATIVE ) {
1940 /* mark used and add to callgraph methods and classes used by NATIVE method */
1941 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1943 if (rt_method->flags & ACC_ABSTRACT) {
1944 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1952 if (m->class->classUsed == NOTUSED)
1953 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1957 /*-------------------------------------------------------------------------------*/
1958 /*--------------------------------------------------------*/
1959 int getdymline(char *line, int max, FILE *inFP) {
1960 if (fgets(line, max, inFP) == NULL)
1963 return strlen((const char *)line);
1967 /*-------------------------------------------------------------------------------*/
1969 methodinfo *getApplicationDynamics ( ) {
1979 if ( (appldynm = fopen("appldynm", "r")) == NULL) {
1980 printf("parseRT - appldynm file: no appldynm file - ok if nothing in rtMissed after Main\n");
1984 if ( getdymline(line,512,appldynm) != 0)
1986 printf("line=%s\n",line); fflush(stdout);
1988 classname = strtok(line," \n");
1989 methname = strtok(NULL," \n");
1990 if (methname == NULL) { /* if no meth */
1991 panic("parseRT - dynamic loaded class/method/desc in appldynm has no method");
1993 desc = strtok(NULL," \n");
1994 if (desc == NULL) { /* if no desc */
1995 panic("parseRT - dynamic loaded class/method/desc in appldynm has no descriptor");
1997 printf("appldynm class=%s meth=%s desc=%s\n",classname, methname,desc); fflush(stdout);
1999 class = class_get(utf_new_char(classname));
2000 if (class == NULL) {
2001 /* class = loader_load_sysclass(NULL, utf_new_char(classname)); */
2002 class = class_new(utf_new_char(classname));
2004 mi = class_fetchmethod(class,utf_new_char(methname), utf_new_char(desc)) ;
2005 printf("+++++--3--+++++\t");
2006 RTparseCGWorklist (mi) ;
2014 /*-------------------------------------------------------------------------------*/
2016 void RT_jit_parse(methodinfo *m)
2020 classinfo *topclass;
2022 /*-- RTA -- *******************************************************/
2025 /*---- java/lang/Object.<clinit> ----*/
2026 if ((firstCall == false) || (true == false))
2029 if (m->methodUsed == USED) return;
2030 printf("MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2031 RTparseCGWorklist (m) ;
2032 /*RTAprint*/ if (pCallgraph >= 1) {
2033 /*RTAprint*/ printCallgraph ();}
2034 /*RTprint*/ //if (pClassHeir >= 1) {
2035 /*RTprint*/ // printRThierarchyInfo(m);
2037 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2039 printf("END MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2045 printf("SSSSSSSSSSSSSSSSSSSSSStatic Analysis \n"); fflush(stdout);
2046 printf("+++++--1--+++++\t");
2047 RTparseCGWorklist (m) ;
2049 class = class_get(utf_new_char("java/lang/Thread"));
2050 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2051 printf("+++++--2--+++++\t");
2052 RTparseCGWorklist (mi) ;
2054 class = class_get(utf_new_char("java/lang/ThreadGroup"));
2055 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2056 printf("+++++--3--+++++\t");
2057 RTparseCGWorklist (mi) ;
2060 class = class_get(utf_new_char("java/lang/Throwable"));
2061 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2062 printf("+++++--4--+++++\t");
2063 RTparseCGWorklist (mi) ;
2065 printf("mainstring=%s=\n",mainstring);fflush(stdout);
2066 /* class = loader_load_sysclass(NULL, utf_new_char(mainString)); */
2067 class = class_new(utf_new_char(mainstring));
2068 mi = class_fetchmethod( class,
2069 utf_new_char("main"),
2070 utf_new_char("([Ljava/lang/String;)V")
2072 printf("+++++--5--+++++\t");
2073 RTparseCGWorklist (mi) ;
2075 printf("+++++--6--+++++\t");
2076 getApplicationDynamics();
2078 printf("-+-+-+-+-+-+-+-+-+-+-33"); fflush(stdout);
2080 /*RTAprint*/ if (pCallgraph >= 1) {
2081 /*RTAprint*/ printCallgraph ();}
2082 /*RTprint*/ //if (pClassHeir >= 1) {
2083 /*RTprint*/ // printRThierarchyInfo(m);
2085 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2087 printf("-+-+-+-+-+-+-+-+-+-+-44"); fflush(stdout);
2088 /** MFREE(callgraph,methodinfo*,MAXCALLGRAPH); causes stack overflow **/
2092 /*-- XTA -- *******************************************************/
2093 if ((XTAOPTbypass) || (opt_xta)) {
2094 if (m->xta != NULL) {
2095 if (m->xta->XTAmethodUsed == USED) return;
2097 mainRTAparseInit (m);
2099 XTAcallgraph[++methXTAlast] = m;
2100 if (m->xta == NULL) {
2101 m->xta = xtainfoInit(m);
2103 m->xta->XTAmethodUsed = USED;
2104 {methodinfo *mi = m;
2105 printf("<");fflush(stdout);
2110 /*-- Call graph work list loop -----------------*/
2111 /*---- XTA call graph worklist -----***/
2112 useXTAcallgraph = true;
2113 if ((useXTAcallgraph) && (opt_xta)) {
2114 printf("USING XTA call graph>>>>>>>>>><<\n");
2116 while (methXTA <= methXTAlast) {
2117 rt_method = XTAcallgraph[methXTA];
2118 printf("xTA CALLGRAPH #%i:",methXTA); fflush(stdout);
2119 method_display(rt_method);
2120 rt_class = rt_method->class;
2121 rt_descriptor = rt_method->descriptor;
2122 rt_jcodelength = rt_method->jcodelength;
2123 rt_jcode = rt_method->jcode;
2125 if (! ( (rt_method->flags & ACC_NATIVE )
2126 || (rt_method->flags & ACC_ABSTRACT) ) ) {
2130 RTAPRINT12bAbstractNative
2131 if (rt_method->flags & ACC_NATIVE ) {
2133 /* mark used and add to callgraph methods and classes used by NATIVE method */
2134 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
2136 if (rt_method->flags & ACC_ABSTRACT) {
2137 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
2144 if (m->class->classUsed == NOTUSED)
2145 m->class->classUsed = USED; /* say Main's class has a method used ??*/
2146 printXTACallgraph ();
2148 if (m->name == utf_MAIN) { /*-- MAIN specific -- */
2149 /*RTAprint*/ if (pCallgraph >= 1) {
2150 /*RTAprint*/ printXTACallgraph (); }
2151 /*RTprint*/ if (pClassHeir >= 1) {
2152 /*RTprint*/ printf("Last RTA Info -+-+-");
2153 /*RTprint*/ printRThierarchyInfo(m);
2155 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2157 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
2159 printf("XTAXTA CALLGRAPHS -SHOULD BE BUT ISNT- returned \n");
2160 //MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
2164 RTAPRINT14CallgraphLast /* was >=2*/
2165 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
2172 * These are local overrides for various environment variables in Emacs.
2173 * Please do not remove this and leave it at the end of the file, where
2174 * Emacs will automagically detect them.
2175 * ---------------------------------------------------------------------
2178 * indent-tabs-mode: t