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 */
19 int I; /* ASTORE /ALOAD index */
23 int methRTmax=MAXCALLGRAPH;
24 methodinfo *callgraph [MAXCALLGRAPH];
28 int methXTAlast = -1;;
29 int methXTAmax=MAXCALLGRAPH;
30 methodinfo *XTAcallgraph[MAXCALLGRAPH];
32 static bool nativecallcompdone=0 ;
34 static bool firstCall= true;
35 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
36 /* so easier to build dynmanic calls file */
38 static utf *utf_MAIN; /* utf_new_char("main"); */
39 static utf *INIT ; /* utf_new_char("<init>"); */
40 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
41 static utf *FINALIZE; /* utf_new_char("finalize"); */
42 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
43 static int missedCnt = 0;
45 static bool useArrayOpcodes = false;
46 static bool useFieldOpcodes = false;
47 static bool useObjectrefOpcodes = false;
48 static bool useOtherOpcodes = false;
50 static s4 currentXTAround = 0;
51 static s4 prevXTAround = -1;
53 #include "jit/parseRTstats.h"
55 /*--------------------------------------------------------------*/
56 /* addToCallgraph - adds to RTA callgraph and */
57 /* sets meth->methodUsed to USED */
58 /*--------------------------------------------------------------*/
59 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
60 callgraph[++methRTlast] = meth ; \
61 meth->methodUsed = USED; \
63 {printf("\n Added to Call Graph #%i:", \
65 printf("\t <used flags c/m> <%i/%i> %i\t", \
66 meth->class->classUsed, \
69 printf(" method name ="); \
70 utf_display(meth->class->name);printf("."); \
71 method_display(meth);fflush(stdout);} \
75 /*--------------------------------------------------------------*/
76 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
79 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
80 if (subs->classUsed == USED) {
81 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
86 if (rtaSubUsed(subs, meth))
93 /*--------------------------------------------------------------*/
94 /* Mark the method with same name /descriptor in topmethod
97 /* Class not marked USED and method defined in this class ->
98 /* -> if Method NOTUSED mark method as MARKED
99 /* Class marked USED and method defined in this class ->
100 /* -> mark method as USED
102 /* Class USED, but method not defined in this class ->
103 /* -> search up the heirarchy and mark method where defined
104 /* if class where method is defined is not USED ->
105 /* -> mark class with defined method as PARTUSED
107 /*--------------------------------------------------------------*/
109 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
111 utf *name = topmethod -> name;
112 utf *descriptor = topmethod -> descriptor;
115 submeth = class_resolvemethod(class, name, descriptor);
117 panic("parse RT: Method not found in class hierarchy");
118 if (submeth->methodUsed == USED) return;
120 if (submeth->class == class) {
122 /*--- Method defined in class -----------------------------*/
123 if (submeth->class->classUsed != USED) {
124 if (submeth->methodUsed == NOTUSED) {
126 /* Class NOT marked USED and method defined in this class ->
127 /* -> if Method NOTUSED mark method as MARKED */
128 if (pWhenMarked >= 1) {
129 printf("MARKED class.method\t");
130 utf_display(submeth->class->name);printf(".");method_display(submeth);
132 if (rtaSubUsed(submeth->class,submeth)) {
133 submeth->class->classUsed = PARTUSED;
134 ADDTOCALLGRAPH(submeth)
137 submeth->methodUsed = MARKED;
142 /* Class IS marked USED and method defined in this class ->
143 /* -> mark method as USED */
144 ADDTOCALLGRAPH(submeth)
146 } /* end defined in class */
149 /*--- Method NOT defined in class -----------------------------*/
150 if (submeth->class->classUsed == NOTUSED) {
151 submeth->class->classUsed = PARTUSED;
152 if (class->classUsed != USED) {
153 submeth->methodUsed = MARKED;
156 if ( (submeth->class->classUsed == USED)
157 || (class->classUsed == USED)) {
158 ADDTOCALLGRAPH(submeth)
160 } /* end NOT defined in class */
163 /*-------------------------------------------------------------------------------*/
164 /* Mark the method with the same name and descriptor as topmethod
165 /* and any subclass where the method is defined and/or class is used
167 /*-------------------------------------------------------------------------------*/
168 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
170 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
171 if (class->sub != NULL) {
174 if (!(topmethod->flags & ACC_FINAL )) {
175 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
177 rtaMarkSubs(subs, topmethod);
184 /*-------------------------------------------------------------------------------*/
185 /* Add Marked methods for input class ci
186 /* Add methods with the same name and descriptor as implemented interfaces
187 /* with the same method name
189 /*-------------------------------------------------------------------------------*/
190 void addMarkedMethods(classinfo *ci) {
193 /* add marked methods to callgraph */
194 for (ii=0; ii<ci->methodscount; ii++) {
195 methodinfo *mi = &(ci->methods[ii]);
196 if (mi->methodUsed == MARKED) {
197 if (pWhenMarked >= 1) {
198 printf("ADDED a method that was MARKED\n");
204 for (jj=0; jj < ci -> interfacescount; jj++) {
205 classinfo *ici = ci -> interfaces [jj];
206 /* use resolve method....!!!! */
207 if (ici -> classUsed != NOTUSED) {
208 for (mm=0; mm< ici->methodscount; mm++) {
209 methodinfo *imi = &(ici->methods[mm]);
211 if ( (imi->methodUsed == USED)
212 && ( (imi->name == mi->name)
213 && (imi->descriptor == mi->descriptor))) {
214 if (pWhenMarked >= 1)
215 printf("ADDED a method that was used by an interface\n");
224 /*-------------------------------------------------------------------------------*/
226 /*-------------------------------------------------------------------------------*/
227 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) {
236 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
238 printf("\tIN SmCalled set : ");
239 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
240 printClassSet(SmCalled->XTAclassSet); printf("\n");
242 printf("\tIN SmCalls set: ");
243 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
244 printClassSet(SmCalls->XTAclassSet); printf("\n");
246 printf("\tIN lastptrInto : (");
247 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
248 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
250 else {printf("NULL) ");}
252 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
253 method_display(lastptrInto->methRef); fflush(stdout);
254 printf("\n");fflush(stdout);
257 /* Get SmCalled ParamType set if null */
258 if (SmCalled->paramClassSet == NULL) {
259 SmCalled->paramClassSet = descriptor2typesL(SmCalled);
262 printf("\tParamPassed\n"); fflush(stdout);
263 printSet(SmCalled->paramClassSet);fflush(stdout);
264 printf("\n"); fflush(stdout);
267 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
268 if (SmCalls->XTAclassSet != NULL)
269 c1 = SmCalls->XTAclassSet->head;
274 /* start with type where left off */
275 c1 = lastptrInto->lastptrIntoClassSet2;
276 c1 = c1 -> nextClass; /* even if NULL */
281 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
284 printf("\tIN SmCalls ... start with :");fflush(stdout);
285 utf_display(c1->classType->name); printf("\n");
289 /* for each Param Class */
290 for ( p=SmCalled->paramClassSet; p != NULL; p = p->nextClass) {
292 /* for each SmCalls class */
293 for (c=c1; c != NULL; c = c->nextClass) {
294 vftbl *p_cl_vt = p->classType->vftbl;
295 vftbl *c_cl_vt = c->classType->vftbl;
297 /* if SmCalls class is in the Params Class range */
298 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
299 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
301 /* add SmCalls class to SmCalledBy Class set */
302 SmCalled->XTAclassSet = SmCalled->XTAclassSet = add2ClassSet(SmCalled->XTAclassSet, c->classType);
308 lastptrInto->lastptrIntoClassSet2 = cprev;
310 printf("\tOUT SmCalled set: ");fflush(stdout);
311 printClassSet(SmCalled->XTAclassSet);fflush(stdout);
313 printf("\tOUT SmCalls set: ");fflush(stdout);
314 printClassSet(SmCalls->XTAclassSet);fflush(stdout);
316 printf("\tOUT lastptrInto="); fflush(stdout);
317 if (lastptrInto->lastptrIntoClassSet2 != NULL)
318 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
320 printf("<rc=%i>\n",rc);fflush(stdout);
325 /*-------------------------------------------------------------------------------*/
326 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
333 printf("xtaPassReturnType \n");
335 /* Get SmCalled return class is null */
336 if ((SmCalled->returnclass == NULL) && (SmCalled->paramClassSet == NULL)) {
337 SmCalled->paramClassSet = descriptor2typesL(SmCalled);
340 if (SmCalled->returnclass == NULL) {
342 printf("\tReturn type is NULL\n");
347 printf("\tReturn type is: ");
348 utf_display(SmCalled->returnclass->name);
351 printf("\tIN SmCalls set: ");
352 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
353 printClassSet(SmCalls->XTAclassSet);
355 printf("\tIN SmCalled set: ");
356 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
357 printClassSet(SmCalled->XTAclassSet);
361 if (SmCalled->XTAclassSet == NULL)
364 cs1 = SmCalled->XTAclassSet->head;
365 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
366 classinfo *c = cs->classType;
367 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
368 vftbl *c_cl_vt = c->vftbl;
370 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
371 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
372 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
373 SmCalls->XTAclassSet = add2ClassSet(SmCalls->XTAclassSet, c);
379 printf("\tOUT SmCalls set: ");
380 printClassSet(SmCalls->XTAclassSet);
385 /*-------------------------------------------------------------------------------*/
386 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
388 if (mi->XTAmethodUsed != USED) { /* if static method not in callgraph */
389 XTAcallgraph[++methXTAlast] = mi;
390 mi->XTAmethodUsed = USED;
394 rt_method->calls = add2MethSet(rt_method->calls, mi);
395 rt_method->calls->tail->monoPoly = monoPoly;
396 mi->calledBy = add2MethSet(mi->calledBy, rt_method);
397 if (mi->calledBy == NULL) panic("mi->calledBy is NULL!!!");
398 if (rt_method->calls == NULL) panic("rt_method->calls is NULL!!!");
402 /*--------------------------------------------------------------*/
403 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
406 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
408 if (inSet(subtypesUsedSet,subs)) {
409 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
414 if (xtaSubUsed(subs, meth, subtypesUsedSet))
421 /*-------------------------------------------------------------------------------*/
422 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
424 utf *name = topmethod -> name;
425 utf *descriptor = topmethod -> descriptor;
429 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
430 method_display(topmethod);
431 submeth = class_resolvemethod(class, name, descriptor);
432 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
433 method_display(submeth);
438 panic("parse XTA: Method not found in class hierarchy");
440 if (rt_method->calls != NULL) {
441 if (inMethSet(rt_method->calls->head,submeth)) return;
444 if (submeth->class == class) {
446 /*--- Method defined in class -----------------------------*/
447 if (inSet(subtypesUsedSet,submeth->class)) {
448 xtaAddCallEdges(submeth,POLY);
451 if (subtypesUsedSet != NULL) {
452 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
453 xtaAddCallEdges(submeth,POLY);
457 rt_method->marked = add2MethSet(rt_method->marked, submeth);
462 /*--- Method NOT defined in class -----------------------------*/
463 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
464 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
465 rt_method->marked = add2MethSet(rt_method->marked, submeth);
466 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->marked);*/
469 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
470 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
471 xtaAddCallEdges(submeth,POLY);
474 } /* end defined in class */
477 /*-------------------------------------------------------------------------------*/
478 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
479 /* xtaPRINTmarkSubs1*/
480 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
481 if (class->sub != NULL) {
484 if (!(topmethod->flags & ACC_FINAL )) {
485 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
486 /* xtaPRINTmarkSubs1 */
487 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
494 /*-------------------------------------------------------------------------------*/
495 /*-------------------------------------------------------------------------------*/
497 int addClassInit(classinfo *ci) {
498 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
501 utf* utf_java_lang_system = utf_new_char("java/lang/System");
502 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
503 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
505 int m, m1=-1, m2=-1, mf=-1, ii;
508 for (m=0; m < ci->methodscount; m++) {
509 /*<clnit> class init method */
510 if (ci->methods[m].name == CLINIT) {
513 /* Special case: System class has an extra initializer method */
514 if ((utf_java_lang_system == ci->name)
515 && (utf_initializeSystemClass == ci->methods[m].name)) {
519 /* Finalize methods */
520 if ((ci->methods[m].name == FINALIZE)
521 && (ci->name != utf_java_lang_Object)) {
527 if (m1 >= 0) { /* No <clinit> available - ignore */
529 /* Get clinit methodinfo ptr */
530 mi = class_findmethod (ci,ci->methods[m1].name , NULL);
533 if ( mi->methodUsed != USED) {
534 mi->class->classUsed = PARTUSED;
539 if ((XTAOPTbypass) || (opt_xta)) {
540 xtaAddCallEdges(mi,MONO);
547 /* Get finalize methodinfo ptr */
548 mi = class_findmethod (ci,ci->methods[mf].name , NULL);
551 if ( mi->methodUsed != USED) {
552 mi->class->classUsed = PARTUSED;
557 if ((XTAOPTbypass) || (opt_xta)) {
558 xtaAddCallEdges(mi,MONO);
562 /*Special Case for System class init:
563 add java/lang/initializeSystemClass to callgraph */
565 /* Get clinit methodinfo ptr */
566 mi = class_findmethod (ci,ci->methods[m2].name , NULL);
569 if ( mi->methodUsed != USED) {
570 mi->class->classUsed = PARTUSED;
575 if ((XTAOPTbypass) || (opt_xta)) {
576 xtaAddCallEdges(mi,MONO);
580 /* add marked methods to callgraph */
581 addMarkedMethods(ci);
587 #define rt_code_get_u1(p) rt_jcode[p]
588 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
589 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
590 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
591 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
592 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
593 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
594 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
598 /*-------------------------------------------------------------------------------*/
599 /*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
602 /* add used interfaces methods to callgraph */
603 for (jj=0; jj < ci -> interfacescount; jj++) {
604 classinfo *ici = ci -> interfaces [jj];
606 if (pWhenMarked >= 1) {
607 printf("BInterface used: ");fflush(stdout);
608 utf_display(ici->name);
609 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
610 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
611 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
612 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
615 /* add class to interfaces list of classes that implement it */
616 ici -> impldBy = addElement(ici -> impldBy, ci);
618 /* if interface class is used */
619 if (ici -> classUsed != NOTUSED) {
621 /* for each interface method implementation that has already been used */
622 for (mm=0; mm< ici->methodscount; mm++) {
623 methodinfo *imi = &(ici->methods[mm]);
624 if (pWhenMarked >= 1) {
625 if (imi->methodUsed != USED) {
626 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
627 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
628 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
631 if (imi->methodUsed == USED) {
632 if (pWhenMarked >= 1) {
633 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
635 /* Mark this method used in the (used) implementing class and its subclasses */
636 printf("MAY ADD methods that was used by an interface\n");
645 /*-------------------------------------------------------------------------------*/
646 /*-------------------------------------------------------------------------------*/
649 /*-------------------------------------------------------------------------------*/
650 void xtaMarkInterfaceSubs(methodinfo *mCalled) {
654 /* for every class that implements the interface of the method called */
655 for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
656 /* add all definitions of this method for this interface */
659 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor);
660 if (submeth == NULL) ; /* search up the heir - ignore for now!!! */
662 classSetNode *subtypesUsedSet = NULL;
664 if (rt_method->XTAclassSet != NULL)
665 subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->XTAclassSet->head);
667 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
668 printSet(subtypesUsedSet);
669 xtaMarkSubs(submeth->class, submeth, subtypesUsedSet);
674 /*-------------------------------------------------------------------------------*/
675 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
679 if (fi->fieldChecked) {
680 if (fi->fldClassType != NULL)
681 return true; /* field has a class type */
685 fi->fieldChecked = true;
687 if (fi->type == TYPE_ADDRESS) {
688 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
690 if (*utf_ptr != 'L') {
691 while (*utf_ptr++ =='[') ;
694 if (*utf_ptr =='L') {
696 if (fi->fldClassType== NULL) {
701 desc = MNEW (char, 256);
702 strcpy (desc,++utf_ptr);
703 cname = strtok(desc,";");
705 printf("STATIC field's type is: %s\n",cname);
708 class = class_get(utf_new_char(cname));
709 fi->fldClassType= class; /* save field's type class ptr */
716 /*-------------------------------------------------------------------------------*/
717 void xtaPassFldPUT(fldSetNode *fN)
719 /* Field type is a class */
721 classSetNode *c1 = NULL;
722 classSetNode *cp = NULL;
723 classSetNode *cprev= NULL;
731 /* Use lastptr so don't check whole XTA class set each time */
734 if (cp->nextClass != NULL)
735 c1 = cp -> nextClass;
738 if (rt_method->XTAclassSet != NULL)
739 c1 = rt_method->XTAclassSet->head;
742 printf("rt XTA class set =");fflush(stdout);
743 printClassSet(rt_method->XTAclassSet);
744 printf("\t\tField class type = ");fflush(stdout);
745 utf_display(fi->fldClassType->name); printf("\n");
749 /*--- PUTSTATIC specific ---*/
750 /* Sx = intersection of type+subtypes(field x) */
751 /* and Sm (where putstatic code is) */
752 for (c=c1; c != NULL; c=c->nextClass) {
753 vftbl *f_cl_vt = fi->fldClassType->vftbl;
754 vftbl *c_cl_vt = c-> classType->vftbl;
756 printf("\tXTA class = ");fflush(stdout);
757 utf_display(c->classType->name);
758 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
759 if (c->nextClass == NULL) {
760 printf("next=NULL ");fflush(stdout);
763 printf("next="); fflush(stdout);
764 utf_display(c->nextClass->classType->name);
765 printf("\n"); fflush(stdout);
768 printf("\t\tField class type = ");fflush(stdout);
769 utf_display(fi->fldClassType->name);
770 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
773 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
774 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
775 fi->XTAclassSet = add2ClassSet(fi->XTAclassSet,c->classType);
779 fN->lastptrPUT = cprev;
781 /*-------------------------------------------------------------------------------*/
782 void xtaPassFldGET(fldSetNode *fN)
784 /* Field type is a class */
786 classSetNode *c1 = NULL;
787 classSetNode *cp = NULL;
788 classSetNode *cprev= NULL;
796 /* Use lastptr so don't check whole XTA class set each time */
799 if (cp->nextClass != NULL)
800 c1 = cp -> nextClass;
803 if (fi->XTAclassSet != NULL)
804 c1 = fi->XTAclassSet->head;
807 printf("fld XTA class set =");fflush(stdout);
808 printClassSet(fi->XTAclassSet);
809 printf("\t\tField class type = ");fflush(stdout);
810 utf_display(fi->fldClassType->name); printf("\n");
814 /*--- GETSTATIC specific ---*/
815 /* Sm = union of Sm and Sx */
816 for (c=c1; c != NULL; c=c->nextClass) {
818 if (rt_method->XTAclassSet ==NULL)
821 if (!(inSet (rt_method->XTAclassSet->head, c->classType) ))
825 rt_method->XTAclassSet
826 = add2ClassSet(rt_method->XTAclassSet,c->classType);
831 fN->lastptrGET = cprev;
835 /*-------------------------------------------------------------------------------*/
836 void xtaPassAllCalledByParams () {
837 methSetNode *SmCalled;
840 printf("calledBy method set: "); fflush(stdout);
841 printMethodSet(rt_method->calledBy); fflush(stdout);
843 if (rt_method->calledBy == NULL)
846 s1 = rt_method->calledBy->head;
847 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
849 printf("SmCalled = "); fflush(stdout);
850 utf_display(SmCalled->methRef->class->name); fflush(stdout);
851 printf(".");fflush(stdout); method_display(SmCalled->methRef);
854 rt_method->chgdSinceLastParse = false;
855 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
859 /*-------------------------------------------------------------------------------*/
860 void xtaAllFldsUsed ( ){
865 if (rt_method->fldsUsed == NULL) return;
867 /* for each field that this method uses */
868 f1 = rt_method->fldsUsed->head;
870 for (f=f1; f != NULL; f = f->nextfldRef) {
878 /*-------------------------------------------------------------------------------*/
879 void xtaMethodCalls_and_sendReturnType()
881 methSetNode *SmCalled; /* for return type */
882 methSetNode *SmCalls; /* for calls param types */
883 methSetNode *s1=NULL;
886 printf("calls method set Return type: ");
887 printMethodSet(rt_method->calls);
888 printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->calls)\n");fflush(stdout);
892 /* for each method that this method calls */
893 if (rt_method->calls == NULL)
896 s1 = SmCalls=rt_method->calls->head;
898 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
899 /* pass param types */
901 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
902 /* if true chgd after its own parse */
903 if (!(SmCalls->methRef->chgdSinceLastParse)) {
904 SmCalls->methRef->chgdSinceLastParse = true;
908 /* for each calledBy method */
909 /* send return type */
910 if (rt_method->calledBy == NULL)
913 s1 = rt_method->calledBy->head;
914 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
917 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
918 printf("."); method_display(SmCalled->methRef);
921 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
922 if (!(SmCalled->methRef->chgdSinceLastParse)) {
923 SmCalled->methRef->chgdSinceLastParse = chgd;
929 /*-------------------------------------------------------------------------------*/
930 static void parseRT()
932 int p; /* java instruction counter */
933 int nextp; /* start of next java instruction */
934 int opcode; /* java opcode */
935 int i; /* temporary for different uses (counters) */
936 bool iswide = false; /* true if last instruction was a wide */
940 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
942 xtaPassAllCalledByParams ();
945 /* scan all java instructions */
947 for (p = 0; p < rt_jcodelength; p = nextp) {
948 opcode = rt_code_get_u1 (p); /* fetch op code */
951 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
954 /*--------------------------------*/
955 /* Code just to get the correct next instruction */
996 /* wider index for loading, storing and incrementing */
1010 /* table jumps ********************************/
1012 case JAVA_LOOKUPSWITCH:
1015 nextp = ALIGN((p + 1), 4);
1016 num = rt_code_get_u4(nextp + 4);
1017 nextp = nextp + 8 + 8 * num;
1022 case JAVA_TABLESWITCH:
1025 nextp = ALIGN ((p + 1),4);
1026 num = rt_code_get_s4(nextp + 4);
1027 num = rt_code_get_s4(nextp + 8) - num;
1028 nextp = nextp + 16 + 4 * num;
1032 /*-------------------------------*/
1033 case JAVA_PUTSTATIC:
1034 i = rt_code_get_u2(p + 1);
1036 constant_FMIref *fr;
1039 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1040 /* descr has type of field ref'd */
1041 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1042 RTAPRINT03putstatic1
1045 /* class with field - marked in addClassinit */
1046 addClassInit(fr->class);
1049 if ((XTAOPTbypass) || (opt_xta))
1051 if (xtaAddFldClassTypeInfo(fi)) {
1052 rt_method->fldsUsed = add2FldSet(rt_method->fldsUsed, fi, true,false);
1058 case JAVA_GETSTATIC:
1059 i = rt_code_get_u2(p + 1);
1061 constant_FMIref *fr;
1064 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1065 /* descr has type of field ref'd */
1066 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1067 RTAPRINT03putstatic1
1070 /* class with field - marked in addClassinit */
1071 addClassInit(fr->class);
1074 if ((XTAOPTbypass) || (opt_xta) )
1076 if (xtaAddFldClassTypeInfo(fi)) {
1077 rt_method->fldsUsed = add2FldSet(rt_method->fldsUsed, fi, false, true);
1086 /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
1087 i = rt_code_get_u2(p + 1);
1089 constant_FMIref *fr;
1095 class_showconstanti(rt_class,i); fflush(stdout);
1096 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1097 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1098 ci = fr->class; /* class with the local field */
1099 /* either current class or inherited (a super) */
1100 /* descriptor has type of field ref'd */
1101 RTAPRINT03putstatic1
1102 /*** OP2A(opcode, fi->type, fi); ***/
1107 /*-------------------- method invocation ---------------------*/
1109 case JAVA_INVOKESTATIC:
1110 i = rt_code_get_u2(p + 1);
1112 constant_FMIref *mr;
1115 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1116 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1118 RTAPRINT04invokestatic1
1119 if (mi->class->classUsed == NOTUSED) {
1120 mi->class->classUsed = USED;
1121 RTAPRINT05invokestatic2
1123 addClassInit(mi->class);
1128 if ((XTAOPTbypass) || (opt_xta)) {
1129 xtaAddCallEdges(mi,MONO);
1134 case JAVA_INVOKESPECIAL:
1135 i = rt_code_get_u2(p + 1);
1137 constant_FMIref *mr;
1141 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1142 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1144 RTAPRINT06invoke_spec_virt1
1145 /*--- PRIVATE Method -----------------------------------------------------*/
1146 if (mi->name != INIT) { /* if method called is PRIVATE */
1147 RTAPRINT07invoke_spec_virt2
1148 RTAPRINT04invokestatic1
1149 /*-- RTA --*/ /* was just markSubs(mi); */
1153 if ((XTAOPTbypass) || (opt_xta)) {
1154 xtaAddCallEdges(mi,MONO);
1159 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1161 /* new class so add marked methods */
1162 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1163 /*--- process NORMAL <init> method ---------------------------------------------*/
1164 if ( mi->methodUsed != USED) {
1166 - mark class as USED and <init> to callgraph */
1169 ci->classUsed = USED;
1170 addMarkedMethods(ci); /* add to callgraph marked methods */
1171 RTAPRINT06Binvoke_spec_init
1172 addUsedInterfaceMethods(ci);
1176 if ((XTAOPTbypass) || (opt_xta)) {
1177 rt_method->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci );
1178 xtaAddCallEdges(mi,MONO);
1179 RTAPRINT06CXTAinvoke_spec_init1
1189 case JAVA_INVOKEVIRTUAL:
1190 i = rt_code_get_u2(p + 1);
1192 constant_FMIref *mr;
1195 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1196 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1199 RTAPRINT07invoke_spec_virt2
1200 mi->monoPoly = POLY;
1201 rtaMarkSubs(mi->class,mi);
1204 if ((XTAOPTbypass) || (opt_xta)) {
1205 classSetNode *subtypesUsedSet = NULL;
1206 if (rt_method->XTAclassSet != NULL)
1207 subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->XTAclassSet->head);
1209 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1210 printSet(subtypesUsedSet);
1212 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1217 case JAVA_INVOKEINTERFACE:
1218 i = rt_code_get_u2(p + 1);
1220 constant_FMIref *mr;
1224 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1225 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1227 if (mi->flags & ACC_STATIC)
1228 panic ("Static/Nonstatic mismatch calling static method");
1231 RTAPRINT08AinvokeInterface0
1232 if (mi->class->classUsed == NOTUSED) {
1233 mi->class->classUsed = USED; /*??PARTUSED;*/
1234 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1237 /* add interface class to list kept in Object */
1238 mi->methodUsed = USED;
1239 mi->monoPoly = POLY;
1241 subs = mi->class->impldBy;
1242 RTAPRINT08invokeInterface1
1243 while (subs != NULL) {
1244 classinfo * isubs = subs->classType;
1245 RTAPRINT09invokeInterface2
1246 /* Mark method (mark/used) in classes that implement the method */
1247 if (isubs->classUsed != NOTUSED) {
1248 methodinfo *submeth;
1250 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
1251 if (submeth != NULL)
1252 submeth->monoPoly = POLY; /* poly even if nosubs */
1253 rtaMarkSubs(isubs, mi);
1255 subs = subs->nextClass;
1259 if ((XTAOPTbypass2) || (opt_xta))
1261 xtaMarkInterfaceSubs(mi);
1266 /* miscellaneous object operations *******/
1269 i = rt_code_get_u2 (p+1);
1275 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1276 if (pWhenMarked >= 1) {
1277 printf("\tclass=");fflush(stdout);
1278 utf_display(ci->name); fflush(stdout);
1279 printf("=\n");fflush(stdout);
1282 if (ci->classUsed != USED) {
1285 ci->classUsed = USED; /* add to heirarchy */
1286 /* Add this class to the implemented by list of the abstract interface */
1287 addUsedInterfaceMethods(ci);
1291 if ((XTAOPTbypass) || (opt_xta))
1293 rt_method->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci ); /*XTA*/
1307 if (p != rt_jcodelength)
1308 panic("Command-sequence crosses code-boundary");
1310 if ((XTAOPTbypass) || (opt_xta))
1311 xtaMethodCalls_and_sendReturnType();
1316 /*-------------------------------------------------------------------------------*/
1317 /* RTA add Native Methods/ Class functions */
1318 /*-------------------------------------------------------------------------------*/
1319 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1328 class = class_get(c1);
1329 if (class == NULL) {
1330 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1333 if (class->classUsed == NOTUSED) {
1334 class->classUsed = USED; /* MARK CLASS USED */
1335 /* add marked methods to callgraph */
1336 addMarkedMethods(class);
1339 meth = class_findmethod (class, m1, d1);
1341 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1342 printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1345 rtaMarkSubs(class,meth);
1348 /*-------------------------------------------------------------------------------*/
1350 void findMarkNativeUsedClass (utf * c) {
1354 class = class_get(c);
1355 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1356 class->classUsed = USED;
1358 /* add marked methods to callgraph */
1359 addMarkedMethods(class);
1363 /*-------------------------------------------------------------------------------*/
1365 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1370 nativecallcompdone = natcall2utf(nativecallcompdone);
1372 for (i=0; i<NATIVECALLSSIZE; i++) {
1373 if (rt_class == nativeCompCalls[i].classname) {
1375 /* find native class.method invoked */
1376 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1378 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1379 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1383 /* mark methods and classes used by this native class.method */
1384 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1385 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1386 /* mark method used */
1387 findMarkNativeUsedMeth(
1388 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1389 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1390 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1393 printf("\nmark method used: "); fflush(stdout);
1394 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1395 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1396 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1400 /* mark class used */
1401 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1415 /*-------------------------------------------------------------------------------*/
1416 /*-------------------------------------------------------------------------------*/
1417 void mainRTAparseInit (methodinfo *m )
1419 /*printf("MAIN_NOT_STARTED \n");*/
1420 if (class_java_lang_Object->sub != NULL) {
1427 utf_MAIN = utf_new_char("main");
1428 INIT = utf_new_char("<init>");
1429 CLINIT = utf_new_char("<clinit>");
1430 FINALIZE = utf_new_char("finalize");
1431 EMPTY_DESC= utf_new_char("()V");
1433 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1434 printf("CACAO - rtMissed file: can't open file to write\n");
1437 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1439 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1440 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1447 if (m->name == utf_MAIN) {
1448 rtMissed = fopen("rtMissed","a");
1449 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1453 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1454 printf("CACAO - rtMissed file: can't open file to write\n");
1457 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1458 utf_fprint(rtMissed,m->class->name);
1459 fprintf(rtMissed," ");
1460 fprintflags(rtMissed,m->flags);
1461 fprintf(rtMissed," ");
1462 utf_fprint(rtMissed,m->name);
1463 fprintf(rtMissed," ");
1464 utf_fprint(rtMissed,m->descriptor);
1465 fprintf(rtMissed,"\n");
1471 /* At moment start RTA before main when parsed */
1472 /* Will definitely use flag with to know if ok to apply in-lining. */
1476 /*-------------------------------------------------------------------------------*/
1477 /*-------------------------------------------------------------------------------*/
1478 /* still need to look at field sets in 2nd pass and clinit ..... */
1479 void XTA_jit_parse2(methodinfo *m)
1482 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1484 /* for each method in XTA worklist = callgraph (use RTA for now) */
1486 while (methRT <= methRTlast) {
1487 rt_method = callgraph[methRT];
1488 rt_class = rt_method->class;
1489 rt_descriptor = rt_method->descriptor;
1490 rt_jcodelength = rt_method->jcodelength;
1491 rt_jcode = rt_method->jcode;
1493 if (! ( (rt_method->flags & ACC_NATIVE )
1494 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1495 if (XTAdebug >= 1) {
1496 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1497 utf_display(rt_class->name); printf("."); fflush(stdout);
1498 method_display(rt_method);
1500 /* if XTA type set changed since last parse */
1501 if (rt_method->chgdSinceLastParse) {
1503 /* get types from methods it is calledBy */
1504 xtaPassAllCalledByParams ();
1506 /* Pass parameter types to methods it calls and send the return type those called by */
1507 xtaMethodCalls_and_sendReturnType();
1512 if (XTAdebug >= 1) {
1514 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1515 printXTACallgraph ();
1518 RTAPRINT14CallgraphLast /*was >=2 */
1519 RTAPRINT15HeirarchyiLast /*was >= 2 */
1523 /*-------------------------------------------------------------------------------*/
1525 void RT_jit_parse(methodinfo *m)
1528 if (m->methodUsed == USED) return;
1529 mainRTAparseInit (m);
1531 /* initialise parameter type descriptor */
1532 callgraph[++methRTlast] = m; /*-- RTA --*/
1533 m->methodUsed = USED;
1534 RTAPRINT11addedtoCallgraph
1536 /* <init> then like a new class so add marked methods to callgraph */
1537 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1541 ci->classUsed = USED;
1542 if (pWhenMarked >= 1) {
1543 printf("Class=");utf_display(ci->name);
1545 /* add marked methods to callgraph */
1546 RTAPRINT11addedtoCallgraph2
1547 addMarkedMethods(ci);
1551 if ((XTAOPTbypass) || (opt_xta)) {
1552 XTAcallgraph[++methXTAlast] = m;
1553 m->XTAmethodUsed = USED;
1554 {methodinfo *mi = m;
1559 /*-- Call graph work list loop -----------------*/
1561 while (methRT <= methRTlast) {
1562 rt_method = callgraph[methRT];
1563 rt_class = rt_method->class;
1564 rt_descriptor = rt_method->descriptor;
1565 rt_jcodelength = rt_method->jcodelength;
1566 rt_jcode = rt_method->jcode;
1568 if (! ( (rt_method->flags & ACC_NATIVE )
1569 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1573 RTAPRINT12bAbstractNative
1574 if (rt_method->flags & ACC_NATIVE ) {
1576 /* mark used and add to callgraph methods and classes used by NATIVE method */
1577 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1579 if (rt_method->flags & ACC_ABSTRACT) {
1580 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1589 if (m->class->classUsed == NOTUSED)
1590 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1591 printXTACallgraph ();
1592 RTAPRINT14CallgraphLast /* was >=2*/
1593 RTAPRINT15HeirarchyiLast /*was >= 2 */
1595 if ((XTAOPTbypass) || (opt_xta)) {
1596 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */