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