Major file restructuring.
[cacao.git] / src / vm / jit / inline / sets.c
1 /* jit/sets.c -
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Carolyn Oates
29
30    $Id: sets.c 557 2003-11-02 22:51:59Z twisti $
31
32 */
33
34
35 #include <stdio.h>
36 #include "sets.h"
37 #include "types.h"
38 #include "global.h"
39
40
41 /*
42  * set.c - functions to manipulate ptr sets.
43  */
44
45  
46 /*------------------------------------------------------------*/
47 /*-- fieldinfo call set fns */
48 /*------------------------------------------------------------*/
49 fldSetNode *inFldSet(fldSetNode *s, fieldinfo *f)
50 {
51         fldSetNode* i;
52         for (i=s; i != NULL; i = i->nextfldRef) {
53                 if (i->fldRef == f) {
54                         return i; /* true = found */
55                 }
56         }
57         return NULL;
58 }
59
60
61 /*------------------------------------------------------------*/
62 /* */
63 fldSetNode *addFldRef(fldSetNode *s, fieldinfo *f)
64 {
65         fldSetNode *s1 = s;
66         if (!inFldSet(s,f)) {
67                 s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
68                 s1->nextfldRef  = s;
69                 s1->fldRef      = f;
70                 s1->writePUT     = false;
71                 s1->readGET    = false;
72                 s1->lastptrPUT = NULL;
73                 s1->lastptrGET = NULL;
74
75                 if (s == NULL)
76                         s1->index = 1;
77                 else
78                         s1->index = s->index+1; 
79         }
80         return s1;
81 }
82
83
84 /*------------------------------------------------------------*/
85 fldSet *add2FldSet(fldSet *sf,  fieldinfo *f, bool wput, bool rget)
86 {
87         fldSetNode *s1;
88         fldSetNode *s;
89  
90         if (sf == NULL) {
91                 sf = createFldSet();
92         }
93         s = sf->head;
94         s1 = inFldSet(s,f);
95         if (s1 == NULL) {
96                 s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
97                 if (sf->head == NULL) {
98                         sf->head  = s1;
99                         sf->pos   = s1;
100                         s1->index = 1;
101                 }        
102                 else {
103                         sf->tail->nextfldRef  = s1;
104                         sf->length++;
105                         s1->index = sf->length;
106         } 
107                 s1->nextfldRef  = NULL;
108                 s1->fldRef      = f;
109                 s1->writePUT    = wput;
110                 s1->readGET     = rget;
111                 s1->lastptrPUT = NULL;
112                 s1->lastptrGET = NULL;
113                 sf->tail = s1;
114         }
115         else    {
116                 if ((s1->writePUT == false) && (wput)) 
117                         s1->writePUT = wput;
118                 if ((s1->readGET == false)  && (rget)) 
119                         s1->readGET  = rget;
120         }
121         return sf;
122 }
123
124
125 /*------------------------------------------------------------*/
126 fldSet *createFldSet( )
127 {
128         fldSet *s;
129         s = (fldSet *)malloc(sizeof(fldSet));
130         s->head = NULL;
131         s->tail = NULL;
132         s->pos  = NULL;
133         s->length = 0;
134         return s;
135 }
136
137
138 /*------------------------------------------------------------*/
139 /*-- methodinfo call set fns */
140 /*------------------------------------------------------------*/
141 int  inMethSet    (methSetNode *s, methodinfo *m)
142 {
143         methSetNode* i;
144         for (i=s; i != NULL; i = i->nextmethRef) {
145                 if (i->methRef == m) {
146                         return (int)1; /* true = found */
147                 }
148         }
149         return (int)0;
150 }
151
152
153 /*------------------------------------------------------------*/
154 methSetNode *addMethRef(methSetNode *s,  methodinfo *m)
155 {
156         methSetNode *s1 = s;
157         if (!inMethSet(s,m)) {
158                 s1 = (methSetNode *)malloc(sizeof(methSetNode));
159                 s1->nextmethRef= s;
160                 s1->methRef = m;
161                 s1->lastptrIntoClassSet2 = NULL;
162                 if (s == NULL)
163                         s1->index = 1;
164                 else
165                         s1->index = s->index+1; 
166                 s1->monoPoly = MONO; 
167         }
168   
169         return s1;
170 }
171
172
173 /*------------------------------------------------------------*/
174 methSet *add2MethSet(methSet *sm,  methodinfo *m)
175 {
176         methSetNode *s1;
177         methSetNode *s;
178  
179         if (sm == NULL) {
180                 sm = createMethSet();
181         }
182         s = sm->head;
183         if (!inMethSet(s,m)) {
184                 s1 = (methSetNode *)malloc(sizeof(methSetNode));
185                 if (sm->head == NULL) {
186                         sm->head = s1;
187                         sm->pos   = s1;
188                         s1->index = 1;
189                 }        
190                 else {
191                         sm->tail->nextmethRef  = s1;
192                         sm->length++;
193                         s1->index = sm->length;
194         }
195                 s1->monoPoly = MONO; 
196                 s1->nextmethRef= NULL;
197                 s1->methRef = m;
198                 s1->lastptrIntoClassSet2 = NULL;
199                 sm->tail = s1;
200         }
201         return sm;
202 }
203
204  
205 /*------------------------------------------------------------*/
206 methSet *createMethSet( )
207 {
208         methSet *s;
209         s = (methSet *)malloc(sizeof(methSet));
210         s->head = NULL;
211         s->tail = NULL;
212         s->pos  = NULL;
213         s->length = 0;
214         return s;
215 }
216
217
218 /*------------------------------------------------------------*/
219 /*-- classinfo XTA set fns  */
220 /*------------------------------------------------------------*/
221 int  inSet    (classSetNode *s, classinfo *c)
222 {
223         classSetNode* i;
224         for (i=s; i != NULL; i = i->nextClass) {
225                 if (i->classType == c) {
226                         return  ((i->index)+1); /* true = found */
227                 }
228         }
229         return (int)0;
230 }
231
232
233 /*------------------------------------------------------------*/
234 classSetNode *addElement(classSetNode *s,  classinfo *c)
235 {
236         classSetNode *s1 = s;
237         if (!inSet(s,c)) {
238                 s1 = (classSetNode *)malloc(sizeof(classSetNode));
239                 s1->nextClass= s;
240                 s1->classType = c;
241                 if (s == NULL)
242                         s1->index = 1;
243                 else
244                         s1->index = s->index+1; 
245         }
246         return s1;
247 }
248
249
250 /*------------------------------------------------------------*/
251 classSet *add2ClassSet(classSet *sc,  classinfo *c)
252 {
253         classSetNode *s1;
254         classSetNode *s;
255  
256         if (sc == NULL) {
257                 sc = createClassSet();
258         }
259         s = sc->head;
260         
261         if (!inSet(s,c)) {
262                 s1 = (classSetNode *)malloc(sizeof(classSetNode));
263                 if (sc->head == NULL) {
264                         sc->head  = s1;
265                         sc->pos   = s1;
266                         s1->index = 1;
267                 }        
268                 else {
269                         sc->tail->nextClass  = s1;
270                         sc->length++;
271                         s1->index = sc->length;
272         } 
273                 s1->classType = c;
274                 s1->nextClass= NULL;
275                 sc->tail  = s1;
276         }
277         return sc;
278 }
279
280
281 /*------------------------------------------------------------*/
282 classSet *createClassSet( )
283 {
284         classSet *s;
285         s = (classSet *)malloc(sizeof(classSet));
286         s->head = NULL;
287         s->tail = NULL;
288         s->pos  = NULL;
289         s->length = 0;
290         return s;
291 }
292
293
294 /*------------------------------------------------------------*/
295 /* Returns:                                                   */
296 /*    -1  c is a subclass   of an existing set element        */
297 /*     0  c class type cone does not overlap any set element  */
298 /*     1  c is a superclass of an existing set element        */
299
300 int inRange (classSetNode *s, classinfo *c)
301 {
302         classSetNode* i;
303         int rc=0;
304
305         for (i=s; i != NULL; i = i->nextClass) {
306                 classinfo *cs = i->classType;
307                 if (cs->vftbl->baseval <= c->vftbl->baseval) {
308                         if (c->vftbl->baseval <= (cs->vftbl->baseval+cs->vftbl->diffval)) {
309                                 rc = -1;  /* subtype */
310                         }
311                 }
312                 else {
313                         if (cs->vftbl->baseval < (c->vftbl->baseval+c->vftbl->diffval)) {
314                                 i->classType = c;   /* replace element with its new super */
315                                 rc  = 1; /* super */
316                         }
317                 }
318     }
319         return rc;
320 }
321
322
323 /*------------------------------------------------------------*/
324 /* adds class if not subtype of an existing set element       */
325 /* if "new" class is super class of an existing element       */
326 /* then replace the existing element with the "new" class     */
327
328 classSetNode *addClassCone(classSetNode *s,  classinfo *c)
329 {
330         classSetNode *s1 = s;
331  
332         if (inRange(s,c) == 0) {
333                 /* not in set nor cone of an existing element so add */
334                 s1 = (classSetNode *)malloc(sizeof(classSetNode));
335                 s1->nextClass= s;
336                 s1->classType = c;
337                 if (s == NULL)
338                         s1->index = 1;
339                 else
340                         s1->index = s->index+1; 
341         }
342         return s1;
343 }
344
345
346 /*------------------------------------------------------------*/
347 classSetNode * intersectSubtypesWithSet(classinfo *t, classSetNode *s) {
348         classSetNode *s1 = NULL;
349         classSetNode *c;
350
351         /* for each s class */
352         for (c=s; c != NULL; c = c->nextClass) {
353                 vftbl *t_cl_vt = t->vftbl;
354                 vftbl *c_cl_vt = c->classType->vftbl;
355
356                 /* if s class is in the t Class range */
357                 if (  (t_cl_vt->baseval <=  c_cl_vt->baseval)
358                           && (c_cl_vt->baseval <= (t_cl_vt->baseval+t_cl_vt->diffval)) ) {
359
360                         /*    add s class to return class set */
361                         s1 = addElement(s1,c->classType);
362                 }
363         }
364         return s1;
365 }
366
367
368 /*------------------------------------------------------------*/
369 int sizeOfSet(classSetNode *s) {
370         /*** need to update */
371         int cnt=0;
372         classSetNode * i;
373         for (i=s; i != NULL; i = i->nextClass) cnt++;
374         return cnt;
375 }
376
377   
378 /*------------------------------------------------------------*/
379 int printSet(classSetNode *s)
380 {
381         classSetNode* i;
382         int cnt=0;
383
384         if (s == NULL) {
385                 printf("Set of types: <");
386                 printf("\t\tEmpty Set\n");
387         }
388         else    {
389                 printf("<%i>Set of types: ",s->index);
390                 for (i=s; i != NULL; i = i->nextClass) {
391                 printf("\t#%i: ",cnt);
392                         if (i->classType == NULL)  {
393                                 printf("NULL CLASS");
394                                 fflush(stdout);
395                         }
396                         else    {
397                                 utf_display(i->classType->name);
398                                 fflush(stdout); 
399                                 printf("<b%i/d%i> ",i->classType->vftbl->baseval,i->classType->vftbl->diffval); 
400                                 fflush(stdout);
401                         }
402                         cnt++;
403                 }
404                 printf(">\n");
405         }
406         return cnt;
407 }
408
409
410 /*------------------------------------------------------------*/
411 int printClassSet(classSet *sc) {
412         if (sc == NULL) {
413                 printf("Class Set not yet created\n");
414                 return 0;
415         }
416         else
417                 return (printSet(sc->head));
418 }
419
420
421 /*------------------------------------------------------------*/
422 int printMethSet(methSetNode *s)
423 {
424         methSetNode* i;
425         int cnt=0;
426
427         if (s == NULL) {
428                 printf("Set of Methods: "); fflush(stdout);
429         printf("\t\tEmpty Set\n"); fflush(stdout);
430         }
431         else    {
432                 printf("<%i>Set of Methods: ",s->index);fflush(stdout); 
433                 for (i=s; i != NULL; i = i->nextmethRef) {
434                 printf("\t#%i: ",cnt);
435
436                         /* class.method */
437                         utf_display(i->methRef->class->name);
438                         printf(".");
439                         method_display(i->methRef);
440
441                         /* lastptr <class> */
442                         printf("\t<");
443                         if (i->lastptrIntoClassSet2 != NULL)
444                                 utf_display(i->lastptrIntoClassSet2->classType->name);
445                         printf(">\n");
446
447                         cnt++;
448                 }
449                 printf("\n");
450         }
451         return cnt;
452 }
453
454
455 /*------------------------------------------------------------*/
456 int printMethodSet(methSet *sm) {
457         if (sm == NULL) {
458                 printf("Method Set not yet created\n");
459                 return 0;
460         }
461         else
462                 return (printMethSet(sm->head));
463 }
464
465
466 /*------------------------------------------------------------*/
467 int printFldSet(fldSetNode *s)
468 {
469         fldSetNode* i;
470         int cnt=0;
471
472         if (s == NULL) {
473                 printf("Set of Fields: ");
474                 printf("\tEmpty Set\n");
475         }
476         else    {
477                 printf("<%i>Set of Fields: ",s->index);
478                 for (i=s; i != NULL; i = i->nextfldRef) {
479                 printf("\t#%i: ",cnt);
480                         printf("(%ir/%iw)",i->writePUT,i->readGET);
481                         field_display(i->fldRef);
482                         cnt++;
483                 }
484                 printf("\n");
485         }
486         return cnt;
487 }
488
489
490 /*------------------------------------------------------------*/
491 int printFieldSet(fldSet *sf) {
492         if (sf == NULL) {
493                 printf("Field Set not yet created\n");
494                 return 0;
495         }
496         else
497                 return (printFldSet(sf->head));
498 }
499 /*------------------------------------------------------------*/
500 /*void destroy_set */
501
502
503 /*
504  * These are local overrides for various environment variables in Emacs.
505  * Please do not remove this and leave it at the end of the file, where
506  * Emacs will automagically detect them.
507  * ---------------------------------------------------------------------
508  * Local variables:
509  * mode: c
510  * indent-tabs-mode: t
511  * c-basic-offset: 4
512  * tab-width: 4
513  * End:
514  */