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