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 619 2003-11-13 13:49:23Z twisti $
36 /*------------ global variables -----------------------------------------*/
37 #define MAXCALLGRAPH 5000
39 bool XTAOPTbypass = false;
40 bool XTAOPTbypass2 = false; /* for now invokeinterface */
41 bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
47 int methRTmax = MAXCALLGRAPH;
48 methodinfo **callgraph;
49 /*methodinfo *callgraph[MAXCALLGRAPH];*/
54 int methXTAmax = MAXCALLGRAPH;
55 methodinfo **XTAcallgraph;
56 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
58 static bool nativecallcompdone=0 ;
60 static bool firstCall= true;
61 static bool AfterMain = false;
62 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
63 /* so easier to build dynmanic calls file */
65 static utf *utf_MAIN; /* utf_new_char("main"); */
66 static utf *INIT ; /* utf_new_char("<init>"); */
67 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
68 static utf *FINALIZE; /* utf_new_char("finalize"); */
69 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
70 static int missedCnt = 0;
73 /*--------------------------------------------------------------*/
74 /* addToCallgraph - adds to RTA callgraph and */
75 /* sets meth->methodUsed to USED */
76 /*--------------------------------------------------------------*/
77 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
78 callgraph[++methRTlast] = meth ; \
79 meth->methodUsed = USED; \
81 {printf("\n Added to Call Graph #%i:", \
83 printf("\t <used flags c/m> <%i/%i> %i\t", \
84 meth->class->classUsed, \
87 printf(" method name ="); \
88 utf_display(meth->class->name);printf("."); \
89 method_display(meth);fflush(stdout);} \
93 /*--------------------------------------------------------------*/
94 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
97 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
98 if (subs->classUsed == USED) {
99 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
104 if (rtaSubUsed(subs, meth))
111 /*--------------------------------------------------------------*/
112 /* Mark the method with same name /descriptor in topmethod */
115 /* Class not marked USED and method defined in this class -> */
116 /* -> if Method NOTUSED mark method as MARKED */
117 /* Class marked USED and method defined in this class -> */
118 /* -> mark method as USED */
120 /* Class USED, but method not defined in this class -> */
121 /* -> search up the heirarchy and mark method where defined */
122 /* if class where method is defined is not USED -> */
123 /* -> mark class with defined method as PARTUSED */
124 /*--------------------------------------------------------------*/
126 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
128 utf *name = topmethod -> name;
129 utf *descriptor = topmethod -> descriptor;
132 submeth = class_resolvemethod(class, name, descriptor);
134 panic("parse RT: Method not found in class hierarchy");
135 if (submeth->methodUsed == USED) return;
137 if (submeth->class == class) {
139 /*--- Method defined in class -----------------------------*/
140 if (submeth->class->classUsed != USED) {
141 if (submeth->methodUsed == NOTUSED) {
143 /* Class NOT marked USED and method defined in this class -> */
144 /* -> if Method NOTUSED mark method as MARKED */
145 if (pWhenMarked >= 1) {
146 printf("MARKED class.method\t");
147 utf_display(submeth->class->name);printf(".");method_display(submeth);
149 if (rtaSubUsed(submeth->class,submeth)) {
150 submeth->class->classUsed = PARTUSED;
151 ADDTOCALLGRAPH(submeth)
154 submeth->methodUsed = MARKED;
159 /* Class IS marked USED and method defined in this class -> */
160 /* -> mark method as USED */
161 ADDTOCALLGRAPH(submeth)
163 } /* end defined in class */
166 /*--- Method NOT defined in class -----------------------------*/
167 if (submeth->class->classUsed == NOTUSED) {
168 submeth->class->classUsed = PARTUSED;
169 if (class->classUsed != USED) {
170 submeth->methodUsed = MARKED;
173 if ( (submeth->class->classUsed == USED)
174 || (class->classUsed == USED)) {
175 ADDTOCALLGRAPH(submeth)
177 } /* end NOT defined in class */
180 /*-------------------------------------------------------------------------------*/
181 /* Mark the method with the same name and descriptor as topmethod */
182 /* and any subclass where the method is defined and/or class is used */
184 /*-------------------------------------------------------------------------------*/
185 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
187 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
188 if (class->sub != NULL) {
191 if (!(topmethod->flags & ACC_FINAL )) {
192 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
194 rtaMarkSubs(subs, topmethod);
201 /*-------------------------------------------------------------------------------*/
202 /* Add Marked methods for input class ci */
203 /* Add methods with the same name and descriptor as implemented interfaces */
204 /* with the same method name */
206 /*-------------------------------------------------------------------------------*/
207 void addMarkedMethods(classinfo *ci) {
210 /* add marked methods to callgraph */
211 for (ii=0; ii<ci->methodscount; ii++) {
212 methodinfo *mi = &(ci->methods[ii]);
213 if (mi->methodUsed == MARKED) {
214 if (pWhenMarked >= 1) {
215 printf("ADDED a method that was MARKED\n");
221 for (jj=0; jj < ci -> interfacescount; jj++) {
222 classinfo *ici = ci -> interfaces [jj];
223 /* use resolve method....!!!! */
224 if (ici -> classUsed != NOTUSED) {
225 for (mm=0; mm< ici->methodscount; mm++) {
226 methodinfo *imi = &(ici->methods[mm]);
228 if ( (imi->methodUsed == USED)
229 && ( (imi->name == mi->name)
230 && (imi->descriptor == mi->descriptor))) {
231 if (pWhenMarked >= 1)
232 printf("ADDED a method that was used by an interface\n");
241 /*-------------------------------------------------------------------------------*/
243 /*-------------------------------------------------------------------------------*/
245 xtainfo *xtainfoInit(methodinfo *m)
253 m ->xta = (xtainfo *) NEW(xtainfo);
254 m ->xta-> XTAmethodUsed = NOTUSED;
255 m ->xta-> XTAclassSet = NULL;
257 m->xta->paramClassSet = NULL;
258 m->xta->calls = NULL;
259 m->xta->calledBy = NULL;
261 m->xta->marked = NULL;
262 /*m ->xta->markedBy = NULL */
263 m->xta->fldsUsed = NULL;
264 /*m ->xta->interfaceCalls = NULL*/
265 m->xta->chgdSinceLastParse = false;
270 xtafldinfo * xtafldinfoInit (fieldinfo *f)
275 f->xta = NEW(xtafldinfo);
277 f->xta->fieldChecked = false; /*XTA*/
278 f->xta->fldClassType = NULL; /*XTA*/
279 f->xta->XTAclassSet = NULL; /*XTA*/
285 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
294 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
296 printf("\tIN SmCalled set : ");
297 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
298 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
300 printf("\tIN SmCalls set: ");
301 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
302 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
304 printf("\tIN lastptrInto : (");
305 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
306 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
308 else {printf("NULL) ");}
310 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
311 method_display(lastptrInto->methRef); fflush(stdout);
312 printf("\n");fflush(stdout);
315 /* Get SmCalled ParamType set if null */
316 if (SmCalled->xta->paramClassSet == NULL) {
317 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
320 printf("\tParamPassed\n"); fflush(stdout);
321 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
322 printf("\n"); fflush(stdout);
325 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
326 if (SmCalls->xta->XTAclassSet != NULL)
327 c1 = SmCalls->xta->XTAclassSet->head;
332 /* start with type where left off */
333 c1 = lastptrInto->lastptrIntoClassSet2;
334 c1 = c1 -> nextClass; /* even if NULL */
339 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
342 printf("\tIN SmCalls ... start with :");fflush(stdout);
343 utf_display(c1->classType->name); printf("\n");
347 /* for each Param Class */
348 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
350 /* for each SmCalls class */
351 for (c=c1; c != NULL; c = c->nextClass) {
352 vftbl *p_cl_vt = p->classType->vftbl;
353 vftbl *c_cl_vt = c->classType->vftbl;
355 /* if SmCalls class is in the Params Class range */
356 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
357 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
359 /* add SmCalls class to SmCalledBy Class set */
360 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
366 lastptrInto->lastptrIntoClassSet2 = cprev;
368 printf("\tOUT SmCalled set: ");fflush(stdout);
369 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
371 printf("\tOUT SmCalls set: ");fflush(stdout);
372 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
374 printf("\tOUT lastptrInto="); fflush(stdout);
375 if (lastptrInto->lastptrIntoClassSet2 != NULL)
376 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
378 printf("<rc=%i>\n",rc);fflush(stdout);
383 /*-------------------------------------------------------------------------------*/
384 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
391 printf("xtaPassReturnType \n");
393 /* Get SmCalled return class is null */
394 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
395 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
398 if (SmCalled->returnclass == NULL) {
400 printf("\tReturn type is NULL\n");
405 printf("\tReturn type is: ");
406 utf_display(SmCalled->returnclass->name);
409 printf("\tIN SmCalls set: ");
410 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
411 printClassSet(SmCalls->xta->XTAclassSet);
413 printf("\tIN SmCalled set: ");
414 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
415 printClassSet(SmCalled->xta->XTAclassSet);
419 if (SmCalled->xta->XTAclassSet == NULL)
422 cs1 = SmCalled->xta->XTAclassSet->head;
423 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
424 classinfo *c = cs->classType;
425 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
426 vftbl *c_cl_vt = c->vftbl;
428 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
429 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
430 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
431 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
437 printf("\tOUT SmCalls set: ");
438 printClassSet(SmCalls->xta->XTAclassSet);
443 /*-------------------------------------------------------------------------------*/
444 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
447 mi->xta = xtainfoInit(mi);
448 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
449 XTAcallgraph[++methXTAlast] = mi;
450 mi->xta->XTAmethodUsed = USED;
451 /** XTAPRINTcallgraph2 */
454 printf("\n XTA Added to Call Graph #%i:",
456 printf(" method name ="); fflush(stdout);
457 if (mi == NULL) panic ("Method ptr NULL!!!");
458 if (mi->class == NULL) panic ("Method class ptr NULL!!!");
459 if (mi->class->name == NULL) panic ("Method class name ptr NULL!!!");
460 utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
461 method_display(mi);fflush(stdout);
466 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
467 rt_method->xta->calls->tail->monoPoly = monoPoly;
468 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
469 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
470 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
474 /*--------------------------------------------------------------*/
475 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
478 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
480 if (inSet(subtypesUsedSet,subs)) {
481 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
486 if (xtaSubUsed(subs, meth, subtypesUsedSet))
493 /*-------------------------------------------------------------------------------*/
494 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
498 utf *name = topmethod -> name;
499 utf *descriptor = topmethod -> descriptor;
501 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
502 method_display(topmethod);
505 submeth = class_resolvemethod(class, name, descriptor);
508 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
509 method_display(submeth);
514 panic("parse XTA: Method not found in class hierarchy");
515 if (submeth->xta == NULL)
516 submeth->xta = xtainfoInit(submeth);
518 if (rt_method->xta->calls != NULL) {
519 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
522 if (submeth->class == class) {
524 /*--- Method defined in class -----------------------------*/
525 if (inSet(subtypesUsedSet,submeth->class)) {
526 xtaAddCallEdges(submeth,POLY);
529 if (subtypesUsedSet != NULL) {
530 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
531 xtaAddCallEdges(submeth,POLY);
535 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
540 /*--- Method NOT defined in class -----------------------------*/
541 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
542 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
543 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
544 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/
547 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
548 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
549 xtaAddCallEdges(submeth,POLY);
552 } /* end defined in class */
555 /*-------------------------------------------------------------------------------*/
556 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
557 /* xtaPRINTmarkSubs1*/
558 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
559 if (class->sub != NULL) {
562 if (!(topmethod->flags & ACC_FINAL )) {
563 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
564 /* xtaPRINTmarkSubs1 */
565 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
572 /*-------------------------------------------------------------------------------*/
573 /*-------------------------------------------------------------------------------*/
575 int addClassInit(classinfo *ci) {
576 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
579 utf* utf_java_lang_system = utf_new_char("java/lang/System");
580 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
581 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
583 int m, m1=-1, m2=-1, mf=-1;
586 for (m=0; m < ci->methodscount; m++) {
587 /*<clnit> class init method */
588 if (ci->methods[m].name == CLINIT) {
591 /* Special case: System class has an extra initializer method */
592 if ((utf_java_lang_system == ci->name)
593 && (utf_initializeSystemClass == ci->methods[m].name)) {
597 /* Finalize methods */
598 if ((ci->methods[m].name == FINALIZE)
599 && (ci->name != utf_java_lang_Object)) {
605 if (m1 >= 0) { /* No <clinit> available - ignore */
607 /* Get clinit methodinfo ptr */
608 mi = class_findmethod (ci,ci->methods[m1].name , NULL);
611 if ( mi->methodUsed != USED) {
612 mi->class->classUsed = PARTUSED;
617 if ((XTAOPTbypass) || (opt_xta)) {
618 xtaAddCallEdges(mi,MONO);
625 /* Get finalize methodinfo ptr */
626 mi = class_findmethod (ci,ci->methods[mf].name , NULL);
629 if ( mi->methodUsed != USED) {
630 mi->class->classUsed = PARTUSED;
635 if ((XTAOPTbypass) || (opt_xta)) {
636 xtaAddCallEdges(mi,MONO);
640 /*Special Case for System class init:
641 add java/lang/initializeSystemClass to callgraph */
643 /* Get clinit methodinfo ptr */
644 mi = class_findmethod (ci,ci->methods[m2].name , NULL);
647 if ( mi->methodUsed != USED) {
648 mi->class->classUsed = PARTUSED;
653 if ((XTAOPTbypass) || (opt_xta)) {
654 xtaAddCallEdges(mi,MONO);
658 /* add marked methods to callgraph */
659 addMarkedMethods(ci);
665 #define rt_code_get_u1(p) rt_jcode[p]
666 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
667 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
668 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
669 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
670 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
671 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
672 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
676 /*-------------------------------------------------------------------------------*/
677 /*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
680 /* add used interfaces methods to callgraph */
681 for (jj=0; jj < ci -> interfacescount; jj++) {
682 classinfo *ici = ci -> interfaces [jj];
684 if (pWhenMarked >= 1) {
685 printf("BInterface used: ");fflush(stdout);
686 utf_display(ici->name);
687 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
688 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
689 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
690 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
693 /* add class to interfaces list of classes that implement it */
694 ici -> impldBy = addElement(ici -> impldBy, ci);
696 /* if interface class is used */
697 if (ici -> classUsed != NOTUSED) {
699 /* for each interface method implementation that has already been used */
700 for (mm=0; mm< ici->methodscount; mm++) {
701 methodinfo *imi = &(ici->methods[mm]);
702 if (pWhenMarked >= 1) {
703 if (imi->methodUsed != USED) {
704 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
705 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
706 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
709 if (imi->methodUsed == USED) {
710 if (pWhenMarked >= 1) {
711 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
713 /* Mark this method used in the (used) implementing class and its subclasses */
714 printf("MAY ADD methods that was used by an interface\n");
723 /*-------------------------------------------------------------------------------*/
724 /*-------------------------------------------------------------------------------*/
727 /*-------------------------------------------------------------------------------*/
728 void xtaMarkInterfaceSubs(methodinfo *mCalled) {
731 /* for every class that implements the interface of the method called */
732 for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
733 /* add all definitions of this method for this interface */
735 classSetNode *subtypesUsedSet = NULL;
737 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor);
738 if (submeth == NULL) { /* search up the heir - ignore for now!!! */
739 submeth = class_resolvemethod(Si->classType, mCalled->name, mCalled->descriptor);
742 if (rt_method->xta->XTAclassSet != NULL)
743 subtypesUsedSet = intersectSubtypesWithSet(Si->classType, rt_method->xta->XTAclassSet->head);
745 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
746 printSet(subtypesUsedSet);
747 xtaMarkSubs(Si->classType, submeth, subtypesUsedSet);
751 /*-------------------------------------------------------------------------------*/
752 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
756 if (fi->xta->fieldChecked) {
757 if (fi->xta->fldClassType != NULL)
758 return true; /* field has a class type */
762 fi->xta->fieldChecked = true;
764 if (fi->type == TYPE_ADDRESS) {
765 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
767 if (*utf_ptr != 'L') {
768 while (*utf_ptr++ =='[') ;
771 if (*utf_ptr =='L') {
773 if (fi->xta->fldClassType== NULL) {
778 desc = MNEW(char, 256);
779 strcpy(desc,++utf_ptr);
780 cname = strtok(desc,";");
782 printf("STATIC field's type is: %s\n",cname);
785 class = class_get(utf_new_char(cname));
786 fi->xta->fldClassType= class; /* save field's type class ptr */
793 /*-------------------------------------------------------------------------------*/
794 void xtaPassFldPUT(fldSetNode *fN)
796 /* Field type is a class */
798 classSetNode *c1 = NULL;
799 classSetNode *cp = NULL;
800 classSetNode *cprev= NULL;
808 /* Use lastptr so don't check whole XTA class set each time */
811 if (cp->nextClass != NULL)
812 c1 = cp -> nextClass;
815 if (rt_method->xta->XTAclassSet != NULL)
816 c1 = rt_method->xta->XTAclassSet->head;
819 printf("rt XTA class set =");fflush(stdout);
820 printClassSet(rt_method->xta->XTAclassSet);
821 printf("\t\tField class type = ");fflush(stdout);
822 utf_display(fi->xta->fldClassType->name); printf("\n");
826 /*--- PUTSTATIC specific ---*/
827 /* Sx = intersection of type+subtypes(field x) */
828 /* and Sm (where putstatic code is) */
829 for (c=c1; c != NULL; c=c->nextClass) {
830 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
831 vftbl *c_cl_vt = c-> classType->vftbl;
833 printf("\tXTA class = ");fflush(stdout);
834 utf_display(c->classType->name);
835 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
836 if (c->nextClass == NULL) {
837 printf("next=NULL ");fflush(stdout);
840 printf("next="); fflush(stdout);
841 utf_display(c->nextClass->classType->name);
842 printf("\n"); fflush(stdout);
845 printf("\t\tField class type = ");fflush(stdout);
846 utf_display(fi->xta->fldClassType->name);
847 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
850 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
851 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
852 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
856 fN->lastptrPUT = cprev;
858 /*-------------------------------------------------------------------------------*/
859 void xtaPassFldGET(fldSetNode *fN)
861 /* Field type is a class */
863 classSetNode *c1 = NULL;
864 classSetNode *cp = NULL;
865 classSetNode *cprev= NULL;
873 /* Use lastptr so don't check whole XTA class set each time */
876 if (cp->nextClass != NULL)
877 c1 = cp -> nextClass;
880 if (fi->xta->XTAclassSet != NULL)
881 c1 = fi->xta->XTAclassSet->head;
884 printf("fld XTA class set =");fflush(stdout);
885 printClassSet(fi->xta->XTAclassSet);
886 printf("\t\tField class type = ");fflush(stdout);
887 utf_display(fi->xta->fldClassType->name); printf("\n");
891 /*--- GETSTATIC specific ---*/
892 /* Sm = union of Sm and Sx */
893 for (c=c1; c != NULL; c=c->nextClass) {
895 if (rt_method->xta->XTAclassSet ==NULL)
898 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
902 rt_method->xta->XTAclassSet
903 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
908 fN->lastptrGET = cprev;
912 /*-------------------------------------------------------------------------------*/
913 void xtaPassAllCalledByParams () {
914 methSetNode *SmCalled;
917 printf("xta->calledBy method set: "); fflush(stdout);
919 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
920 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
922 if (rt_method->xta->calledBy == NULL)
925 s1 = rt_method->xta->calledBy->head;
926 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
928 printf("SmCalled = "); fflush(stdout);
929 utf_display(SmCalled->methRef->class->name); fflush(stdout);
930 printf(".");fflush(stdout); method_display(SmCalled->methRef);
933 rt_method->xta->chgdSinceLastParse = false;
934 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
938 /*-------------------------------------------------------------------------------*/
939 void xtaAllFldsUsed ( ){
942 /* bool chgd = false */
944 if (rt_method->xta->fldsUsed == NULL) return;
946 /* for each field that this method uses */
947 f1 = rt_method->xta->fldsUsed->head;
949 for (f=f1; f != NULL; f = f->nextfldRef) {
957 /*-------------------------------------------------------------------------------*/
958 void xtaMethodCalls_and_sendReturnType()
960 methSetNode *SmCalled; /* for return type */
961 methSetNode *SmCalls; /* for calls param types */
962 methSetNode *s1=NULL;
965 printf("calls method set Return type: ");
966 printMethodSet(rt_method->xta->calls);
970 /* for each method that this method calls */
971 if (rt_method->xta->calls == NULL)
974 s1 = SmCalls=rt_method->xta->calls->head;
976 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
977 /* pass param types */
979 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
980 /* if true chgd after its own parse */
981 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
982 SmCalls->methRef->xta->chgdSinceLastParse = true;
986 /* for each calledBy method */
987 /* send return type */
988 if (rt_method->xta->calledBy == NULL)
991 s1 = rt_method->xta->calledBy->head;
992 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
995 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
996 printf("."); method_display(SmCalled->methRef);
999 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
1000 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1001 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
1007 /*-------------------------------------------------------------------------------*/
1008 static void parseRT()
1010 int p; /* java instruction counter */
1011 int nextp; /* start of next java instruction */
1012 int opcode; /* java opcode */
1013 int i; /* temporary for different uses (counters) */
1014 bool iswide = false; /* true if last instruction was a wide */
1018 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1019 printf("XTA parseRT():"); fflush(stdout);
1020 method_display(rt_method);
1021 if (rt_method->xta == NULL)
1022 xtainfoInit (rt_method);
1023 xtaPassAllCalledByParams ();
1024 printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1028 /* scan all java instructions */
1030 for (p = 0; p < rt_jcodelength; p = nextp) {
1031 opcode = rt_code_get_u1 (p); /* fetch op code */
1034 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
1037 /*--------------------------------*/
1038 /* Code just to get the correct next instruction */
1077 /* wider index for loading, storing and incrementing */
1091 /* table jumps ********************************/
1093 case JAVA_LOOKUPSWITCH:
1096 nextp = ALIGN((p + 1), 4);
1097 num = rt_code_get_u4(nextp + 4);
1098 nextp = nextp + 8 + 8 * num;
1103 case JAVA_TABLESWITCH:
1106 nextp = ALIGN ((p + 1),4);
1107 num = rt_code_get_s4(nextp + 4);
1108 num = rt_code_get_s4(nextp + 8) - num;
1109 nextp = nextp + 16 + 4 * num;
1113 /*-------------------------------*/
1114 case JAVA_PUTSTATIC:
1115 i = rt_code_get_u2(p + 1);
1117 constant_FMIref *fr;
1120 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1121 /* descr has type of field ref'd */
1122 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1123 RTAPRINT03putstatic1
1126 /* class with field - marked in addClassinit */
1127 addClassInit(fr->class);
1130 if ((XTAOPTbypass) || (opt_xta))
1132 if (fi->xta == NULL)
1133 fi->xta = xtafldinfoInit(fi);
1134 if (xtaAddFldClassTypeInfo(fi)) {
1135 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1141 case JAVA_GETSTATIC:
1142 i = rt_code_get_u2(p + 1);
1144 constant_FMIref *fr;
1147 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1148 /* descr has type of field ref'd */
1149 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1150 RTAPRINT03putstatic1
1153 /* class with field - marked in addClassinit */
1154 addClassInit(fr->class);
1157 if ((XTAOPTbypass) || (opt_xta) )
1159 if (fi->xta == NULL)
1160 fi->xta = xtafldinfoInit(fi);
1161 if (xtaAddFldClassTypeInfo(fi)) {
1162 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1170 /*-------------------- method invocation ---------------------*/
1172 case JAVA_INVOKESTATIC:
1173 i = rt_code_get_u2(p + 1);
1175 constant_FMIref *mr;
1178 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1179 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1181 RTAPRINT04invokestatic1
1182 if (mi->class->classUsed == NOTUSED) {
1183 mi->class->classUsed = USED;
1184 RTAPRINT05invokestatic2
1186 addClassInit(mi->class);
1191 if ((XTAOPTbypass) || (opt_xta)) {
1192 xtaAddCallEdges(mi,MONO);
1197 case JAVA_INVOKESPECIAL:
1198 i = rt_code_get_u2(p + 1);
1200 constant_FMIref *mr;
1204 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1205 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1207 RTAPRINT06invoke_spec_virt1
1208 /*--- PRIVATE Method -----------------------------------------------------*/
1209 if (mi->name != INIT) { /* if method called is PRIVATE */
1210 RTAPRINT07invoke_spec_virt2
1211 RTAPRINT04invokestatic1
1212 /*-- RTA --*/ /* was just markSubs(mi); */
1216 if ((XTAOPTbypass) || (opt_xta)) {
1217 xtaAddCallEdges(mi,MONO);
1222 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1224 /* new class so add marked methods */
1225 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1226 /*--- process NORMAL <init> method ---------------------------------------------*/
1227 if ( mi->methodUsed != USED) {
1229 - mark class as USED and <init> to callgraph */
1232 ci->classUsed = USED;
1233 addMarkedMethods(ci); /* add to callgraph marked methods */
1234 RTAPRINT06Binvoke_spec_init
1235 addUsedInterfaceMethods(ci);
1239 if ((XTAOPTbypass) || (opt_xta)) {
1240 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1241 xtaAddCallEdges(mi,MONO);
1242 RTAPRINT06CXTAinvoke_spec_init1
1252 case JAVA_INVOKEVIRTUAL:
1253 i = rt_code_get_u2(p + 1);
1255 constant_FMIref *mr;
1258 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1259 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1262 RTAPRINT07invoke_spec_virt2
1263 mi->monoPoly = POLY;
1264 rtaMarkSubs(mi->class,mi);
1267 if ((XTAOPTbypass) || (opt_xta)) {
1268 classSetNode *subtypesUsedSet = NULL;
1269 if (rt_method->xta->XTAclassSet != NULL)
1270 subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1272 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1273 printSet(subtypesUsedSet);
1275 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1280 case JAVA_INVOKEINTERFACE:
1281 i = rt_code_get_u2(p + 1);
1283 constant_FMIref *mr;
1286 classSetNode *subtypesUsedSet = NULL;
1288 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1289 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1291 if (mi->flags & ACC_STATIC)
1292 panic ("Static/Nonstatic mismatch calling static method");
1295 RTAPRINT08AinvokeInterface0
1296 if (mi->class->classUsed == NOTUSED) {
1297 mi->class->classUsed = USED; /*??PARTUSED;*/
1298 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1301 /* add interface class to list kept in Object */
1302 mi->methodUsed = USED;
1303 mi->monoPoly = POLY;
1305 subs = mi->class->impldBy;
1306 RTAPRINT08invokeInterface1
1307 while (subs != NULL) {
1308 classinfo * isubs = subs->classType;
1309 RTAPRINT09invokeInterface2
1310 /* Mark method (mark/used) in classes that implement the method */
1311 if (isubs->classUsed != NOTUSED) {
1312 methodinfo *submeth;
1314 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
1315 if (submeth != NULL)
1316 submeth->monoPoly = POLY; /* poly even if nosubs */
1317 rtaMarkSubs(isubs, mi);
1320 if ((XTAOPTbypass) || (opt_xta))
1322 if (rt_method->xta->XTAclassSet != NULL)
1324 intersectSubtypesWithSet
1325 (subs->classType, rt_method->xta->XTAclassSet->head);
1327 printf(" \nXTA subtypesUsedSet: ");
1329 printSet(subtypesUsedSet);
1330 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
1333 subs = subs->nextClass;
1337 if ((XTAOPTbypass2) || (opt_xta))
1339 xtaMarkInterfaceSubs(mi);
1344 /* miscellaneous object operations *******/
1347 i = rt_code_get_u2 (p+1);
1351 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1352 if (pWhenMarked >= 1) {
1353 printf("\tclass=");fflush(stdout);
1354 utf_display(ci->name); fflush(stdout);
1355 printf("=\n");fflush(stdout);
1358 if (ci->classUsed != USED) {
1360 ci->classUsed = USED; /* add to heirarchy */
1361 /* Add this class to the implemented by list of the abstract interface */
1362 addUsedInterfaceMethods(ci);
1366 if ((XTAOPTbypass) || (opt_xta))
1368 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1382 if (p != rt_jcodelength)
1383 panic("Command-sequence crosses code-boundary");
1385 if ((XTAOPTbypass) || (opt_xta))
1386 xtaMethodCalls_and_sendReturnType();
1391 /*-------------------------------------------------------------------------------*/
1392 /* RTA add Native Methods/ Class functions */
1393 /*-------------------------------------------------------------------------------*/
1394 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1399 class = class_get(c1);
1400 if (class == NULL) {
1401 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1404 if (class->classUsed == NOTUSED) {
1405 class->classUsed = USED; /* MARK CLASS USED */
1406 /* add marked methods to callgraph */
1407 addMarkedMethods(class);
1410 meth = class_findmethod (class, m1, d1);
1412 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1413 printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1416 rtaMarkSubs(class,meth);
1419 /*-------------------------------------------------------------------------------*/
1421 void findMarkNativeUsedClass (utf * c) {
1424 class = class_get(c);
1425 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1426 class->classUsed = USED;
1428 /* add marked methods to callgraph */
1429 addMarkedMethods(class);
1433 /*-------------------------------------------------------------------------------*/
1435 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1439 nativecallcompdone = natcall2utf(nativecallcompdone);
1441 for (i=0; i<NATIVECALLSSIZE; i++) {
1442 if (rt_class == nativeCompCalls[i].classname) {
1444 /* find native class.method invoked */
1445 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1447 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1448 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1452 /* mark methods and classes used by this native class.method */
1453 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1454 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1455 /* mark method used */
1456 findMarkNativeUsedMeth(
1457 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1458 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1459 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1462 printf("\nmark method used: "); fflush(stdout);
1463 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1464 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1465 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1469 /* mark class used */
1470 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1484 /*-------------------------------------------------------------------------------*/
1485 /*-------------------------------------------------------------------------------*/
1486 void mainRTAparseInit (methodinfo *m )
1488 /*printf("MAIN_NOT_STARTED \n");*/
1489 if (class_java_lang_Object->sub != NULL) {
1496 utf_MAIN = utf_new_char("main");
1497 INIT = utf_new_char("<init>");
1498 CLINIT = utf_new_char("<clinit>");
1499 FINALIZE = utf_new_char("finalize");
1500 EMPTY_DESC= utf_new_char("()V");
1502 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1503 printf("CACAO - rtMissed file: can't open file to write\n");
1506 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1508 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1509 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1513 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1514 if ((XTAOPTbypass) || (opt_xta)) {
1515 printf("XTAXTA CALLGRAPHS allocated\n");
1516 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1520 if (m->name == utf_MAIN) {
1521 rtMissed = fopen("rtMissed","a");
1522 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1527 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1528 printf("CACAO - rtMissed file: can't open file to write\n");
1531 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1532 utf_fprint(rtMissed,m->class->name);
1533 fprintf(rtMissed," ");
1534 fprintflags(rtMissed,m->flags);
1535 fprintf(rtMissed," ");
1536 utf_fprint(rtMissed,m->name);
1537 fprintf(rtMissed," ");
1538 utf_fprint(rtMissed,m->descriptor);
1539 fprintf(rtMissed,"\n");
1544 printf("#%i : ",methRT);
1545 printf("Method missed by static analysis Main parse. See rtMissed file");
1546 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1550 /* At moment start RTA before main when parsed */
1551 /* Will definitely use flag with to know if ok to apply in-lining. */
1555 /*-------------------------------------------------------------------------------*/
1556 /*-------------------------------------------------------------------------------*/
1557 /* still need to look at field sets in 2nd pass and clinit ..... */
1558 void XTA_jit_parse2(methodinfo *m)
1561 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1563 /* for each method in XTA worklist = callgraph (use RTA for now) */
1565 while (methRT <= methRTlast) {
1566 rt_method = callgraph[methRT];
1567 rt_class = rt_method->class;
1568 rt_descriptor = rt_method->descriptor;
1569 rt_jcodelength = rt_method->jcodelength;
1570 rt_jcode = rt_method->jcode;
1572 if (! ( (rt_method->flags & ACC_NATIVE )
1573 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1574 if (XTAdebug >= 1) {
1575 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1576 utf_display(rt_class->name); printf("."); fflush(stdout);
1577 method_display(rt_method);
1579 /* if XTA type set changed since last parse */
1580 if (rt_method->xta->chgdSinceLastParse) {
1582 /* get types from methods it is calledBy */
1583 xtaPassAllCalledByParams ();
1585 /* Pass parameter types to methods it calls and send the return type those called by */
1586 xtaMethodCalls_and_sendReturnType();
1591 if (XTAdebug >= 1) {
1593 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1594 printXTACallgraph ();
1597 RTAPRINT14CallgraphLast /*was >=2 */
1598 RTAPRINT15HeirarchyiLast /*was >= 2 */
1602 /*-------------------------------------------------------------------------------*/
1604 void RT_jit_parse(methodinfo *m)
1607 if (m->methodUsed == USED) return;
1608 mainRTAparseInit (m);
1610 /* initialise parameter type descriptor */
1611 callgraph[++methRTlast] = m; /*-- RTA --*/
1612 m->methodUsed = USED;
1613 RTAPRINT11addedtoCallgraph
1614 /* <init> then like a new class so add marked methods to callgraph */
1615 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1618 ci->classUsed = USED;
1619 if (pWhenMarked >= 1) {
1620 printf("Class=");utf_display(ci->name);
1622 /* add marked methods to callgraph */
1623 RTAPRINT11addedtoCallgraph2
1624 addMarkedMethods(ci);
1628 if ((XTAOPTbypass) || (opt_xta)) {
1629 XTAcallgraph[++methXTAlast] = m;
1630 if (m->xta == NULL) {
1631 m->xta = xtainfoInit(m);
1633 m->xta->XTAmethodUsed = USED;
1634 {methodinfo *mi = m;
1639 /*-- Call graph work list loop -----------------*/
1641 while (methRT <= methRTlast) {
1642 rt_method = callgraph[methRT];
1643 rt_class = rt_method->class;
1644 rt_descriptor = rt_method->descriptor;
1645 rt_jcodelength = rt_method->jcodelength;
1646 rt_jcode = rt_method->jcode;
1648 if (! ( (rt_method->flags & ACC_NATIVE )
1649 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1653 RTAPRINT12bAbstractNative
1654 if (rt_method->flags & ACC_NATIVE ) {
1656 /* mark used and add to callgraph methods and classes used by NATIVE method */
1657 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1659 if (rt_method->flags & ACC_ABSTRACT) {
1660 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1669 if (m->class->classUsed == NOTUSED)
1670 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1671 printXTACallgraph ();
1672 RTAPRINT14CallgraphLast /* was >=2*/
1673 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
1675 if (m->name == utf_MAIN) {
1676 /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
1677 /*RTAprint*/ printCallgraph (); }
1679 /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
1680 /*RTprint*/ printf("Last RTA Info -");
1681 /*RTprint*/ printRThierarchyInfo(m);
1683 /*RTprint*/ printObjectClassHeirarchy1( );
1686 if ((XTAOPTbypass) || (opt_xta)) {
1687 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
1690 MFREE(callgraph,methodinfo*,MAXCALLGRAPH);
1691 if ((XTAOPTbypass) || (opt_xta)) {
1692 printf("XTAXTA CALLGRAPHS returned \n");
1693 MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
1702 * These are local overrides for various environment variables in Emacs.
1703 * Please do not remove this and leave it at the end of the file, where
1704 * Emacs will automagically detect them.
1705 * ---------------------------------------------------------------------
1708 * indent-tabs-mode: t