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