1 /********************** parseRT.h ******************************************
2 Parser and print functions for Rapid Type Analyis
3 used to only compile methods that may actually be used.
4 ***************************************************************************/
7 #include "parseRTprint.h" /* RTAPRINT trace/info/debug prints */
10 /*------------ global variables -----------------------------------------*/
11 #define MAXCALLGRAPH 5000
13 bool XTAOPTbypass = false;
14 bool XTAOPTbypass2 = false; /* for now invokeinterface */
15 bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
21 int methRTmax=MAXCALLGRAPH;
22 static methodinfo **callgraph;
23 /*methodinfo *callgraph[MAXCALLGRAPH];*/
27 int methXTAlast = -1;;
28 int methXTAmax=MAXCALLGRAPH;
29 static methodinfo **XTAcallgraph;
30 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
32 static bool nativecallcompdone=0 ;
34 static bool firstCall= true;
35 static bool AfterMain = false;
36 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
37 /* so easier to build dynmanic calls file */
39 static utf *utf_MAIN; /* utf_new_char("main"); */
40 static utf *INIT ; /* utf_new_char("<init>"); */
41 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
42 static utf *FINALIZE; /* utf_new_char("finalize"); */
43 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
44 static int missedCnt = 0;
46 #include "jit/parseRTstats.h"
48 /*--------------------------------------------------------------*/
49 /* addToCallgraph - adds to RTA callgraph and */
50 /* sets meth->methodUsed to USED */
51 /*--------------------------------------------------------------*/
52 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
53 callgraph[++methRTlast] = meth ; \
54 meth->methodUsed = USED; \
56 {printf("\n Added to Call Graph #%i:", \
58 printf("\t <used flags c/m> <%i/%i> %i\t", \
59 meth->class->classUsed, \
62 printf(" method name ="); \
63 utf_display(meth->class->name);printf("."); \
64 method_display(meth);fflush(stdout);} \
68 /*--------------------------------------------------------------*/
69 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
72 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
73 if (subs->classUsed == USED) {
74 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
79 if (rtaSubUsed(subs, meth))
86 /*--------------------------------------------------------------*/
87 /* Mark the method with same name /descriptor in topmethod */
90 /* Class not marked USED and method defined in this class -> */
91 /* -> if Method NOTUSED mark method as MARKED */
92 /* Class marked USED and method defined in this class -> */
93 /* -> mark method as USED */
95 /* Class USED, but method not defined in this class -> */
96 /* -> search up the heirarchy and mark method where defined */
97 /* if class where method is defined is not USED -> */
98 /* -> mark class with defined method as PARTUSED */
99 /*--------------------------------------------------------------*/
101 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
103 utf *name = topmethod -> name;
104 utf *descriptor = topmethod -> descriptor;
107 submeth = class_resolvemethod(class, name, descriptor);
109 panic("parse RT: Method not found in class hierarchy");
110 if (submeth->methodUsed == USED) return;
112 if (submeth->class == class) {
114 /*--- Method defined in class -----------------------------*/
115 if (submeth->class->classUsed != USED) {
116 if (submeth->methodUsed == NOTUSED) {
118 /* Class NOT marked USED and method defined in this class -> */
119 /* -> if Method NOTUSED mark method as MARKED */
120 if (pWhenMarked >= 1) {
121 printf("MARKED class.method\t");
122 utf_display(submeth->class->name);printf(".");method_display(submeth);
124 if (rtaSubUsed(submeth->class,submeth)) {
125 submeth->class->classUsed = PARTUSED;
126 ADDTOCALLGRAPH(submeth)
129 submeth->methodUsed = MARKED;
134 /* Class IS marked USED and method defined in this class -> */
135 /* -> mark method as USED */
136 ADDTOCALLGRAPH(submeth)
138 } /* end defined in class */
141 /*--- Method NOT defined in class -----------------------------*/
142 if (submeth->class->classUsed == NOTUSED) {
143 submeth->class->classUsed = PARTUSED;
144 if (class->classUsed != USED) {
145 submeth->methodUsed = MARKED;
148 if ( (submeth->class->classUsed == USED)
149 || (class->classUsed == USED)) {
150 ADDTOCALLGRAPH(submeth)
152 } /* end NOT defined in class */
155 /*-------------------------------------------------------------------------------*/
156 /* Mark the method with the same name and descriptor as topmethod */
157 /* and any subclass where the method is defined and/or class is used */
159 /*-------------------------------------------------------------------------------*/
160 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
162 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
163 if (class->sub != NULL) {
166 if (!(topmethod->flags & ACC_FINAL )) {
167 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
169 rtaMarkSubs(subs, topmethod);
176 /*-------------------------------------------------------------------------------*/
177 /* Add Marked methods for input class ci */
178 /* Add methods with the same name and descriptor as implemented interfaces */
179 /* with the same method name */
181 /*-------------------------------------------------------------------------------*/
182 void addMarkedMethods(classinfo *ci) {
185 /* add marked methods to callgraph */
186 for (ii=0; ii<ci->methodscount; ii++) {
187 methodinfo *mi = &(ci->methods[ii]);
188 if (mi->methodUsed == MARKED) {
189 if (pWhenMarked >= 1) {
190 printf("ADDED a method that was MARKED\n");
196 for (jj=0; jj < ci -> interfacescount; jj++) {
197 classinfo *ici = ci -> interfaces [jj];
198 /* use resolve method....!!!! */
199 if (ici -> classUsed != NOTUSED) {
200 for (mm=0; mm< ici->methodscount; mm++) {
201 methodinfo *imi = &(ici->methods[mm]);
203 if ( (imi->methodUsed == USED)
204 && ( (imi->name == mi->name)
205 && (imi->descriptor == mi->descriptor))) {
206 if (pWhenMarked >= 1)
207 printf("ADDED a method that was used by an interface\n");
216 /*-------------------------------------------------------------------------------*/
218 /*-------------------------------------------------------------------------------*/
220 xtainfo * xtainfoInit (methodinfo *m) {
222 if (m->xta != NULL) return m->xta;
223 m ->xta = (xtainfo *)malloc(sizeof(xtainfo));
224 m ->xta-> XTAmethodUsed = NOTUSED;
225 m ->xta-> XTAclassSet = NULL;
227 m ->xta-> paramClassSet = NULL;
228 m ->xta-> calls = NULL;
229 m ->xta-> calledBy = NULL;
231 m ->xta-> marked = NULL;
232 /*m ->xta-> markedBy = NULL */
233 m ->xta-> fldsUsed = NULL;
234 /*m ->xta-> interfaceCalls = NULL*/
235 m ->xta-> chgdSinceLastParse = false;
239 xtafldinfo * xtafldinfoInit (fieldinfo *f) {
241 if (f->xta != NULL) return f->xta;
243 f ->xta = (xtafldinfo *)malloc(sizeof(xtafldinfo));
244 f -> xta-> fieldChecked = false; /*XTA*/
245 f -> xta-> fldClassType = NULL; /*XTA*/
246 f -> xta-> XTAclassSet = NULL; /*XTA*/
250 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) {
259 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
261 printf("\tIN SmCalled set : ");
262 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
263 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
265 printf("\tIN SmCalls set: ");
266 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
267 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
269 printf("\tIN lastptrInto : (");
270 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
271 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
273 else {printf("NULL) ");}
275 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
276 method_display(lastptrInto->methRef); fflush(stdout);
277 printf("\n");fflush(stdout);
280 /* Get SmCalled ParamType set if null */
281 if (SmCalled->xta->paramClassSet == NULL) {
282 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
285 printf("\tParamPassed\n"); fflush(stdout);
286 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
287 printf("\n"); fflush(stdout);
290 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
291 if (SmCalls->xta->XTAclassSet != NULL)
292 c1 = SmCalls->xta->XTAclassSet->head;
297 /* start with type where left off */
298 c1 = lastptrInto->lastptrIntoClassSet2;
299 c1 = c1 -> nextClass; /* even if NULL */
304 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
307 printf("\tIN SmCalls ... start with :");fflush(stdout);
308 utf_display(c1->classType->name); printf("\n");
312 /* for each Param Class */
313 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
315 /* for each SmCalls class */
316 for (c=c1; c != NULL; c = c->nextClass) {
317 vftbl *p_cl_vt = p->classType->vftbl;
318 vftbl *c_cl_vt = c->classType->vftbl;
320 /* if SmCalls class is in the Params Class range */
321 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
322 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
324 /* add SmCalls class to SmCalledBy Class set */
325 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
331 lastptrInto->lastptrIntoClassSet2 = cprev;
333 printf("\tOUT SmCalled set: ");fflush(stdout);
334 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
336 printf("\tOUT SmCalls set: ");fflush(stdout);
337 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
339 printf("\tOUT lastptrInto="); fflush(stdout);
340 if (lastptrInto->lastptrIntoClassSet2 != NULL)
341 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
343 printf("<rc=%i>\n",rc);fflush(stdout);
348 /*-------------------------------------------------------------------------------*/
349 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
356 printf("xtaPassReturnType \n");
358 /* Get SmCalled return class is null */
359 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
360 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
363 if (SmCalled->returnclass == NULL) {
365 printf("\tReturn type is NULL\n");
370 printf("\tReturn type is: ");
371 utf_display(SmCalled->returnclass->name);
374 printf("\tIN SmCalls set: ");
375 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
376 printClassSet(SmCalls->xta->XTAclassSet);
378 printf("\tIN SmCalled set: ");
379 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
380 printClassSet(SmCalled->xta->XTAclassSet);
384 if (SmCalled->xta->XTAclassSet == NULL)
387 cs1 = SmCalled->xta->XTAclassSet->head;
388 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
389 classinfo *c = cs->classType;
390 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
391 vftbl *c_cl_vt = c->vftbl;
393 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
394 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
395 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
396 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
402 printf("\tOUT SmCalls set: ");
403 printClassSet(SmCalls->xta->XTAclassSet);
408 /*-------------------------------------------------------------------------------*/
409 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
412 mi->xta = xtainfoInit(mi);
413 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
414 XTAcallgraph[++methXTAlast] = mi;
415 mi->xta->XTAmethodUsed = USED;
416 // XTAPRINTcallgraph2
419 printf("\n XTA Added to Call Graph #%i:",
421 printf(" method name ="); fflush(stdout);
422 if (mi == NULL) panic ("Method ptr NULL!!!");
423 if (mi->class == NULL) panic ("Method class ptr NULL!!!");
424 if (mi->class->name == NULL) panic ("Method class name ptr NULL!!!");
425 utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
426 method_display(mi);fflush(stdout);
431 printf("AA1 "); fflush(stdout);
432 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
433 rt_method->xta->calls->tail->monoPoly = monoPoly;
434 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
435 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
436 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
440 /*--------------------------------------------------------------*/
441 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
444 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
446 if (inSet(subtypesUsedSet,subs)) {
447 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
452 if (xtaSubUsed(subs, meth, subtypesUsedSet))
459 /*-------------------------------------------------------------------------------*/
460 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
464 utf *name = topmethod -> name;
465 utf *descriptor = topmethod -> descriptor;
467 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
468 method_display(topmethod);
471 submeth = class_resolvemethod(class, name, descriptor);
474 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
475 method_display(submeth);
480 panic("parse XTA: Method not found in class hierarchy");
481 if (submeth->xta == NULL)
482 submeth->xta = xtainfoInit(submeth);
484 if (rt_method->xta->calls != NULL) {
485 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
488 if (submeth->class == class) {
490 /*--- Method defined in class -----------------------------*/
491 if (inSet(subtypesUsedSet,submeth->class)) {
492 xtaAddCallEdges(submeth,POLY);
495 if (subtypesUsedSet != NULL) {
496 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
497 xtaAddCallEdges(submeth,POLY);
501 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
506 /*--- Method NOT defined in class -----------------------------*/
507 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
508 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
509 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
510 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/
513 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
514 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
515 xtaAddCallEdges(submeth,POLY);
518 } /* end defined in class */
521 /*-------------------------------------------------------------------------------*/
522 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
523 /* xtaPRINTmarkSubs1*/
524 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
525 if (class->sub != NULL) {
528 if (!(topmethod->flags & ACC_FINAL )) {
529 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
530 /* xtaPRINTmarkSubs1 */
531 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
538 /*-------------------------------------------------------------------------------*/
539 /*-------------------------------------------------------------------------------*/
541 int addClassInit(classinfo *ci) {
542 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
545 utf* utf_java_lang_system = utf_new_char("java/lang/System");
546 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
547 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
549 int m, m1=-1, m2=-1, mf=-1;
552 for (m=0; m < ci->methodscount; m++) {
553 /*<clnit> class init method */
554 if (ci->methods[m].name == CLINIT) {
557 /* Special case: System class has an extra initializer method */
558 if ((utf_java_lang_system == ci->name)
559 && (utf_initializeSystemClass == ci->methods[m].name)) {
563 /* Finalize methods */
564 if ((ci->methods[m].name == FINALIZE)
565 && (ci->name != utf_java_lang_Object)) {
571 if (m1 >= 0) { /* No <clinit> available - ignore */
573 /* Get clinit methodinfo ptr */
574 mi = class_findmethod (ci,ci->methods[m1].name , NULL);
577 if ( mi->methodUsed != USED) {
578 mi->class->classUsed = PARTUSED;
583 if ((XTAOPTbypass) || (opt_xta)) {
584 xtaAddCallEdges(mi,MONO);
591 /* Get finalize methodinfo ptr */
592 mi = class_findmethod (ci,ci->methods[mf].name , NULL);
595 if ( mi->methodUsed != USED) {
596 mi->class->classUsed = PARTUSED;
601 if ((XTAOPTbypass) || (opt_xta)) {
602 xtaAddCallEdges(mi,MONO);
606 /*Special Case for System class init:
607 add java/lang/initializeSystemClass to callgraph */
609 /* Get clinit methodinfo ptr */
610 mi = class_findmethod (ci,ci->methods[m2].name , NULL);
613 if ( mi->methodUsed != USED) {
614 mi->class->classUsed = PARTUSED;
619 if ((XTAOPTbypass) || (opt_xta)) {
620 xtaAddCallEdges(mi,MONO);
624 /* add marked methods to callgraph */
625 addMarkedMethods(ci);
631 #define rt_code_get_u1(p) rt_jcode[p]
632 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
633 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
634 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
635 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
636 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
637 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
638 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
642 /*-------------------------------------------------------------------------------*/
643 /*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
646 /* add used interfaces methods to callgraph */
647 for (jj=0; jj < ci -> interfacescount; jj++) {
648 classinfo *ici = ci -> interfaces [jj];
650 if (pWhenMarked >= 1) {
651 printf("BInterface used: ");fflush(stdout);
652 utf_display(ici->name);
653 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
654 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
655 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
656 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
659 /* add class to interfaces list of classes that implement it */
660 ici -> impldBy = addElement(ici -> impldBy, ci);
662 /* if interface class is used */
663 if (ici -> classUsed != NOTUSED) {
665 /* for each interface method implementation that has already been used */
666 for (mm=0; mm< ici->methodscount; mm++) {
667 methodinfo *imi = &(ici->methods[mm]);
668 if (pWhenMarked >= 1) {
669 if (imi->methodUsed != USED) {
670 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
671 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
672 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
675 if (imi->methodUsed == USED) {
676 if (pWhenMarked >= 1) {
677 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
679 /* Mark this method used in the (used) implementing class and its subclasses */
680 printf("MAY ADD methods that was used by an interface\n");
689 /*-------------------------------------------------------------------------------*/
690 /*-------------------------------------------------------------------------------*/
693 /*-------------------------------------------------------------------------------*/
694 void xtaMarkInterfaceSubs(methodinfo *mCalled) {
697 /* for every class that implements the interface of the method called */
698 for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
699 /* add all definitions of this method for this interface */
702 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor);
703 if (submeth == NULL) ; /* search up the heir - ignore for now!!! */
705 classSetNode *subtypesUsedSet = NULL;
707 if (rt_method->xta->XTAclassSet != NULL)
708 subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->xta->XTAclassSet->head);
710 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
711 printSet(subtypesUsedSet);
712 xtaMarkSubs(submeth->class, submeth, subtypesUsedSet);
717 /*-------------------------------------------------------------------------------*/
718 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
722 if (fi->xta->fieldChecked) {
723 if (fi->xta->fldClassType != NULL)
724 return true; /* field has a class type */
728 fi->xta->fieldChecked = true;
730 if (fi->type == TYPE_ADDRESS) {
731 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
733 if (*utf_ptr != 'L') {
734 while (*utf_ptr++ =='[') ;
737 if (*utf_ptr =='L') {
739 if (fi->xta->fldClassType== NULL) {
744 desc = MNEW (char, 256);
745 strcpy (desc,++utf_ptr);
746 cname = strtok(desc,";");
748 printf("STATIC field's type is: %s\n",cname);
751 class = class_get(utf_new_char(cname));
752 fi->xta->fldClassType= class; /* save field's type class ptr */
759 /*-------------------------------------------------------------------------------*/
760 void xtaPassFldPUT(fldSetNode *fN)
762 /* Field type is a class */
764 classSetNode *c1 = NULL;
765 classSetNode *cp = NULL;
766 classSetNode *cprev= NULL;
774 /* Use lastptr so don't check whole XTA class set each time */
777 if (cp->nextClass != NULL)
778 c1 = cp -> nextClass;
781 if (rt_method->xta->XTAclassSet != NULL)
782 c1 = rt_method->xta->XTAclassSet->head;
785 printf("rt XTA class set =");fflush(stdout);
786 printClassSet(rt_method->xta->XTAclassSet);
787 printf("\t\tField class type = ");fflush(stdout);
788 utf_display(fi->xta->fldClassType->name); printf("\n");
792 /*--- PUTSTATIC specific ---*/
793 /* Sx = intersection of type+subtypes(field x) */
794 /* and Sm (where putstatic code is) */
795 for (c=c1; c != NULL; c=c->nextClass) {
796 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
797 vftbl *c_cl_vt = c-> classType->vftbl;
799 printf("\tXTA class = ");fflush(stdout);
800 utf_display(c->classType->name);
801 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
802 if (c->nextClass == NULL) {
803 printf("next=NULL ");fflush(stdout);
806 printf("next="); fflush(stdout);
807 utf_display(c->nextClass->classType->name);
808 printf("\n"); fflush(stdout);
811 printf("\t\tField class type = ");fflush(stdout);
812 utf_display(fi->xta->fldClassType->name);
813 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
816 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
817 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
818 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
822 fN->lastptrPUT = cprev;
824 /*-------------------------------------------------------------------------------*/
825 void xtaPassFldGET(fldSetNode *fN)
827 /* Field type is a class */
829 classSetNode *c1 = NULL;
830 classSetNode *cp = NULL;
831 classSetNode *cprev= NULL;
839 /* Use lastptr so don't check whole XTA class set each time */
842 if (cp->nextClass != NULL)
843 c1 = cp -> nextClass;
846 if (fi->xta->XTAclassSet != NULL)
847 c1 = fi->xta->XTAclassSet->head;
850 printf("fld XTA class set =");fflush(stdout);
851 printClassSet(fi->xta->XTAclassSet);
852 printf("\t\tField class type = ");fflush(stdout);
853 utf_display(fi->xta->fldClassType->name); printf("\n");
857 /*--- GETSTATIC specific ---*/
858 /* Sm = union of Sm and Sx */
859 for (c=c1; c != NULL; c=c->nextClass) {
861 if (rt_method->xta->XTAclassSet ==NULL)
864 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
868 rt_method->xta->XTAclassSet
869 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
874 fN->lastptrGET = cprev;
878 /*-------------------------------------------------------------------------------*/
879 void xtaPassAllCalledByParams () {
880 methSetNode *SmCalled;
883 printf("xta->calledBy method set: "); fflush(stdout);
884 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
886 if (rt_method->xta->calledBy == NULL)
889 s1 = rt_method->xta->calledBy->head;
890 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
892 printf("SmCalled = "); fflush(stdout);
893 utf_display(SmCalled->methRef->class->name); fflush(stdout);
894 printf(".");fflush(stdout); method_display(SmCalled->methRef);
897 rt_method->xta->chgdSinceLastParse = false;
898 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
902 /*-------------------------------------------------------------------------------*/
903 void xtaAllFldsUsed ( ){
906 /* bool chgd = false */
908 if (rt_method->xta->fldsUsed == NULL) return;
910 /* for each field that this method uses */
911 f1 = rt_method->xta->fldsUsed->head;
913 for (f=f1; f != NULL; f = f->nextfldRef) {
921 /*-------------------------------------------------------------------------------*/
922 void xtaMethodCalls_and_sendReturnType()
924 methSetNode *SmCalled; /* for return type */
925 methSetNode *SmCalls; /* for calls param types */
926 methSetNode *s1=NULL;
929 printf("calls method set Return type: ");
930 printMethodSet(rt_method->xta->calls);
931 printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->xta->calls)\n");fflush(stdout);
935 /* for each method that this method calls */
936 if (rt_method->xta->calls == NULL)
939 s1 = SmCalls=rt_method->xta->calls->head;
941 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
942 /* pass param types */
944 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
945 /* if true chgd after its own parse */
946 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
947 SmCalls->methRef->xta->chgdSinceLastParse = true;
951 /* for each calledBy method */
952 /* send return type */
953 if (rt_method->xta->calledBy == NULL)
956 s1 = rt_method->xta->calledBy->head;
957 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
960 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
961 printf("."); method_display(SmCalled->methRef);
964 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
965 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
966 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
972 /*-------------------------------------------------------------------------------*/
973 static void parseRT()
975 int p; /* java instruction counter */
976 int nextp; /* start of next java instruction */
977 int opcode; /* java opcode */
978 int i; /* temporary for different uses (counters) */
979 bool iswide = false; /* true if last instruction was a wide */
983 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
985 xtaPassAllCalledByParams ();
988 /* scan all java instructions */
990 for (p = 0; p < rt_jcodelength; p = nextp) {
991 opcode = rt_code_get_u1 (p); /* fetch op code */
994 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
997 /*--------------------------------*/
998 /* Code just to get the correct next instruction */
1037 /* wider index for loading, storing and incrementing */
1051 /* table jumps ********************************/
1053 case JAVA_LOOKUPSWITCH:
1056 nextp = ALIGN((p + 1), 4);
1057 num = rt_code_get_u4(nextp + 4);
1058 nextp = nextp + 8 + 8 * num;
1063 case JAVA_TABLESWITCH:
1066 nextp = ALIGN ((p + 1),4);
1067 num = rt_code_get_s4(nextp + 4);
1068 num = rt_code_get_s4(nextp + 8) - num;
1069 nextp = nextp + 16 + 4 * num;
1073 /*-------------------------------*/
1074 case JAVA_PUTSTATIC:
1075 i = rt_code_get_u2(p + 1);
1077 constant_FMIref *fr;
1080 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1081 /* descr has type of field ref'd */
1082 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1083 RTAPRINT03putstatic1
1086 /* class with field - marked in addClassinit */
1087 addClassInit(fr->class);
1090 if ((XTAOPTbypass) || (opt_xta))
1092 if (fi->xta == NULL)
1093 fi->xta = xtafldinfoInit(fi);
1094 if (xtaAddFldClassTypeInfo(fi)) {
1095 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1101 case JAVA_GETSTATIC:
1102 i = rt_code_get_u2(p + 1);
1104 constant_FMIref *fr;
1107 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1108 /* descr has type of field ref'd */
1109 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1110 RTAPRINT03putstatic1
1113 /* class with field - marked in addClassinit */
1114 addClassInit(fr->class);
1117 if ((XTAOPTbypass) || (opt_xta) )
1119 if (fi->xta == NULL)
1120 fi->xta = xtafldinfoInit(fi);
1121 if (xtaAddFldClassTypeInfo(fi)) {
1122 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1130 /*-------------------- method invocation ---------------------*/
1132 case JAVA_INVOKESTATIC:
1133 i = rt_code_get_u2(p + 1);
1135 constant_FMIref *mr;
1138 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1139 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1141 RTAPRINT04invokestatic1
1142 if (mi->class->classUsed == NOTUSED) {
1143 mi->class->classUsed = USED;
1144 RTAPRINT05invokestatic2
1146 addClassInit(mi->class);
1151 if ((XTAOPTbypass) || (opt_xta)) {
1152 xtaAddCallEdges(mi,MONO);
1157 case JAVA_INVOKESPECIAL:
1158 i = rt_code_get_u2(p + 1);
1160 constant_FMIref *mr;
1164 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1165 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1167 RTAPRINT06invoke_spec_virt1
1168 /*--- PRIVATE Method -----------------------------------------------------*/
1169 if (mi->name != INIT) { /* if method called is PRIVATE */
1170 RTAPRINT07invoke_spec_virt2
1171 RTAPRINT04invokestatic1
1172 /*-- RTA --*/ /* was just markSubs(mi); */
1176 if ((XTAOPTbypass) || (opt_xta)) {
1177 xtaAddCallEdges(mi,MONO);
1182 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1184 /* new class so add marked methods */
1185 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1186 /*--- process NORMAL <init> method ---------------------------------------------*/
1187 if ( mi->methodUsed != USED) {
1189 - mark class as USED and <init> to callgraph */
1192 ci->classUsed = USED;
1193 addMarkedMethods(ci); /* add to callgraph marked methods */
1194 RTAPRINT06Binvoke_spec_init
1195 addUsedInterfaceMethods(ci);
1199 if ((XTAOPTbypass) || (opt_xta)) {
1200 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1201 xtaAddCallEdges(mi,MONO);
1202 RTAPRINT06CXTAinvoke_spec_init1
1212 case JAVA_INVOKEVIRTUAL:
1213 i = rt_code_get_u2(p + 1);
1215 constant_FMIref *mr;
1218 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1219 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1222 RTAPRINT07invoke_spec_virt2
1223 mi->monoPoly = POLY;
1224 rtaMarkSubs(mi->class,mi);
1227 if ((XTAOPTbypass) || (opt_xta)) {
1228 classSetNode *subtypesUsedSet = NULL;
1229 if (rt_method->xta->XTAclassSet != NULL)
1230 subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1232 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1233 printSet(subtypesUsedSet);
1235 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1240 case JAVA_INVOKEINTERFACE:
1241 i = rt_code_get_u2(p + 1);
1243 constant_FMIref *mr;
1247 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1248 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1250 if (mi->flags & ACC_STATIC)
1251 panic ("Static/Nonstatic mismatch calling static method");
1254 RTAPRINT08AinvokeInterface0
1255 if (mi->class->classUsed == NOTUSED) {
1256 mi->class->classUsed = USED; /*??PARTUSED;*/
1257 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1260 /* add interface class to list kept in Object */
1261 mi->methodUsed = USED;
1262 mi->monoPoly = POLY;
1264 subs = mi->class->impldBy;
1265 RTAPRINT08invokeInterface1
1266 while (subs != NULL) {
1267 classinfo * isubs = subs->classType;
1268 RTAPRINT09invokeInterface2
1269 /* Mark method (mark/used) in classes that implement the method */
1270 if (isubs->classUsed != NOTUSED) {
1271 methodinfo *submeth;
1273 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
1274 if (submeth != NULL)
1275 submeth->monoPoly = POLY; /* poly even if nosubs */
1276 rtaMarkSubs(isubs, mi);
1278 subs = subs->nextClass;
1282 if ((XTAOPTbypass2) || (opt_xta))
1284 xtaMarkInterfaceSubs(mi);
1289 /* miscellaneous object operations *******/
1292 i = rt_code_get_u2 (p+1);
1296 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1297 if (pWhenMarked >= 1) {
1298 printf("\tclass=");fflush(stdout);
1299 utf_display(ci->name); fflush(stdout);
1300 printf("=\n");fflush(stdout);
1303 if (ci->classUsed != USED) {
1305 ci->classUsed = USED; /* add to heirarchy */
1306 /* Add this class to the implemented by list of the abstract interface */
1307 addUsedInterfaceMethods(ci);
1311 if ((XTAOPTbypass) || (opt_xta))
1313 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1327 if (p != rt_jcodelength)
1328 panic("Command-sequence crosses code-boundary");
1330 if ((XTAOPTbypass) || (opt_xta))
1331 xtaMethodCalls_and_sendReturnType();
1336 /*-------------------------------------------------------------------------------*/
1337 /* RTA add Native Methods/ Class functions */
1338 /*-------------------------------------------------------------------------------*/
1339 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1344 class = class_get(c1);
1345 if (class == NULL) {
1346 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1349 if (class->classUsed == NOTUSED) {
1350 class->classUsed = USED; /* MARK CLASS USED */
1351 /* add marked methods to callgraph */
1352 addMarkedMethods(class);
1355 meth = class_findmethod (class, m1, d1);
1357 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1358 printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1361 rtaMarkSubs(class,meth);
1364 /*-------------------------------------------------------------------------------*/
1366 void findMarkNativeUsedClass (utf * c) {
1369 class = class_get(c);
1370 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1371 class->classUsed = USED;
1373 /* add marked methods to callgraph */
1374 addMarkedMethods(class);
1378 /*-------------------------------------------------------------------------------*/
1380 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1384 nativecallcompdone = natcall2utf(nativecallcompdone);
1386 for (i=0; i<NATIVECALLSSIZE; i++) {
1387 if (rt_class == nativeCompCalls[i].classname) {
1389 /* find native class.method invoked */
1390 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1392 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1393 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1397 /* mark methods and classes used by this native class.method */
1398 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1399 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1400 /* mark method used */
1401 findMarkNativeUsedMeth(
1402 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1403 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1404 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1407 printf("\nmark method used: "); fflush(stdout);
1408 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1409 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1410 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1414 /* mark class used */
1415 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1429 /*-------------------------------------------------------------------------------*/
1430 /*-------------------------------------------------------------------------------*/
1431 void mainRTAparseInit (methodinfo *m )
1433 /*printf("MAIN_NOT_STARTED \n");*/
1434 if (class_java_lang_Object->sub != NULL) {
1441 utf_MAIN = utf_new_char("main");
1442 INIT = utf_new_char("<init>");
1443 CLINIT = utf_new_char("<clinit>");
1444 FINALIZE = utf_new_char("finalize");
1445 EMPTY_DESC= utf_new_char("()V");
1447 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1448 printf("CACAO - rtMissed file: can't open file to write\n");
1451 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1453 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1454 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1458 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1459 if ((XTAOPTbypass) || (opt_xta)) {
1460 printf("XTAXTA CALLGRAPHS allocated\n");
1461 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1465 if (m->name == utf_MAIN) {
1466 rtMissed = fopen("rtMissed","a");
1467 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1472 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1473 printf("CACAO - rtMissed file: can't open file to write\n");
1476 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1477 utf_fprint(rtMissed,m->class->name);
1478 fprintf(rtMissed," ");
1479 fprintflags(rtMissed,m->flags);
1480 fprintf(rtMissed," ");
1481 utf_fprint(rtMissed,m->name);
1482 fprintf(rtMissed," ");
1483 utf_fprint(rtMissed,m->descriptor);
1484 fprintf(rtMissed,"\n");
1489 printf("#%i : ",methRT);
1490 printf("Method missed by static analysis Main parse. See rtMissed file");
1491 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1495 /* At moment start RTA before main when parsed */
1496 /* Will definitely use flag with to know if ok to apply in-lining. */
1500 /*-------------------------------------------------------------------------------*/
1501 /*-------------------------------------------------------------------------------*/
1502 /* still need to look at field sets in 2nd pass and clinit ..... */
1503 void XTA_jit_parse2(methodinfo *m)
1506 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1508 /* for each method in XTA worklist = callgraph (use RTA for now) */
1510 while (methRT <= methRTlast) {
1511 rt_method = callgraph[methRT];
1512 rt_class = rt_method->class;
1513 rt_descriptor = rt_method->descriptor;
1514 rt_jcodelength = rt_method->jcodelength;
1515 rt_jcode = rt_method->jcode;
1517 if (! ( (rt_method->flags & ACC_NATIVE )
1518 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1519 if (XTAdebug >= 1) {
1520 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1521 utf_display(rt_class->name); printf("."); fflush(stdout);
1522 method_display(rt_method);
1524 /* if XTA type set changed since last parse */
1525 if (rt_method->xta->chgdSinceLastParse) {
1527 /* get types from methods it is calledBy */
1528 xtaPassAllCalledByParams ();
1530 /* Pass parameter types to methods it calls and send the return type those called by */
1531 xtaMethodCalls_and_sendReturnType();
1536 if (XTAdebug >= 1) {
1538 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1539 printXTACallgraph ();
1542 RTAPRINT14CallgraphLast /*was >=2 */
1543 RTAPRINT15HeirarchyiLast /*was >= 2 */
1547 /*-------------------------------------------------------------------------------*/
1549 void RT_jit_parse(methodinfo *m)
1552 if (m->methodUsed == USED) return;
1553 mainRTAparseInit (m);
1555 /* initialise parameter type descriptor */
1556 callgraph[++methRTlast] = m; /*-- RTA --*/
1557 m->methodUsed = USED;
1558 RTAPRINT11addedtoCallgraph
1559 /* <init> then like a new class so add marked methods to callgraph */
1560 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1563 ci->classUsed = USED;
1564 if (pWhenMarked >= 1) {
1565 printf("Class=");utf_display(ci->name);
1567 /* add marked methods to callgraph */
1568 RTAPRINT11addedtoCallgraph2
1569 addMarkedMethods(ci);
1573 if ((XTAOPTbypass) || (opt_xta)) {
1574 XTAcallgraph[++methXTAlast] = m;
1575 if (m->xta == NULL) {
1576 m->xta = xtainfoInit(m);
1578 m->xta->XTAmethodUsed = USED;
1579 {methodinfo *mi = m;
1584 /*-- Call graph work list loop -----------------*/
1586 while (methRT <= methRTlast) {
1587 rt_method = callgraph[methRT];
1588 rt_class = rt_method->class;
1589 rt_descriptor = rt_method->descriptor;
1590 rt_jcodelength = rt_method->jcodelength;
1591 rt_jcode = rt_method->jcode;
1593 if (! ( (rt_method->flags & ACC_NATIVE )
1594 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1598 RTAPRINT12bAbstractNative
1599 if (rt_method->flags & ACC_NATIVE ) {
1601 /* mark used and add to callgraph methods and classes used by NATIVE method */
1602 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1604 if (rt_method->flags & ACC_ABSTRACT) {
1605 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1614 if (m->class->classUsed == NOTUSED)
1615 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1616 printXTACallgraph ();
1617 RTAPRINT14CallgraphLast /* was >=2*/
1618 //RTAPRINT15HeirarchyiLast /*was >= 2 */
1620 if ((XTAOPTbypass) || (opt_xta)) {
1621 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
1624 /**** DO NOT free if RTA or XTA for now
1625 if (m->name == utf_MAIN) {
1626 MFREE(callgraph,methodinfo*,MAXCALLGRAPH);
1627 if ((XTAOPTbypass) || (opt_xta)) {
1628 printf("XTAXTA CALLGRAPHS returned \n");
1629 MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);