Linker related stuff (mostly from loader.c/global.h).
[cacao.git] / src / vm / linker.c
1 /* src/vm/linker.c - class linker functions
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: Reinhard Grafl
28
29    Changes: Andreas Krall
30             Roman Obermaiser
31             Mark Probst
32             Edwin Steiner
33             Christian Thalinger
34
35    $Id: linker.c 2101 2005-03-28 21:59:45Z twisti $
36
37 */
38
39
40 #include "mm/memory.h"
41 #include "native/native.h"
42 #include "vm/builtin.h"
43 #include "vm/class.h"
44 #include "vm/exceptions.h"
45 #include "vm/options.h"
46 #include "vm/statistics.h"
47 #include "vm/jit/codegen.inc.h"
48
49
50 /* global variables ***********************************************************/
51
52 static s4 interfaceindex;       /* sequential numbering of interfaces         */
53 static s4 classvalue;
54
55
56 /* private functions **********************************************************/
57
58 static classinfo *link_class_intern(classinfo *c);
59 static arraydescriptor *link_array(classinfo *c);
60 static void linker_compute_class_values(classinfo *c);
61 static void linker_compute_subclasses(classinfo *c);
62 static void linker_addinterface(classinfo *c, classinfo *ic);
63 static s4 class_highestinterface(classinfo *c);
64
65
66 /* linker_init *****************************************************************
67
68    Initializes the linker subsystem.
69
70 *******************************************************************************/
71
72 void linker_init(void)
73 {
74         /* reset interface index */
75
76         interfaceindex = 0;
77 }
78
79
80 /* link_class ******************************************************************
81
82    Wrapper function for link_class_intern to ease monitor enter/exit
83    and exception handling.
84
85 *******************************************************************************/
86
87 classinfo *class_link(classinfo *c)
88 {
89         classinfo *r;
90
91 #if defined(USE_THREADS)
92         /* enter a monitor on the class */
93
94         builtin_monitorenter((java_objectheader *) c);
95 #endif
96
97         /* maybe the class is already linked */
98         if (c->linked) {
99 #if defined(USE_THREADS)
100                 builtin_monitorexit((java_objectheader *) c);
101 #endif
102
103                 return c;
104         }
105
106 #if defined(STATISTICS)
107         /* measure time */
108
109         if (getcompilingtime)
110                 compilingtime_stop();
111
112         if (getloadingtime)
113                 loadingtime_start();
114 #endif
115
116         /* call the internal function */
117         r = link_class_intern(c);
118
119         /* if return value is NULL, we had a problem and the class is not linked */
120         if (!r)
121                 c->linked = false;
122
123 #if defined(STATISTICS)
124         /* measure time */
125
126         if (getloadingtime)
127                 loadingtime_stop();
128
129         if (getcompilingtime)
130                 compilingtime_start();
131 #endif
132
133 #if defined(USE_THREADS)
134         /* leave the monitor */
135
136         builtin_monitorexit((java_objectheader *) c);
137 #endif
138
139         return r;
140 }
141
142
143 /* link_class_intern ***********************************************************
144
145    Tries to link a class. The function calculates the length in bytes
146    that an instance of this class requires as well as the VTBL for
147    methods and interface methods.
148         
149 *******************************************************************************/
150
151 static classinfo *link_class_intern(classinfo *c)
152 {
153         classinfo *super;             /* super class                              */
154         classinfo *tc;                /* temporary class variable                 */
155         s4 supervftbllength;          /* vftbllegnth of super class               */
156         s4 vftbllength;               /* vftbllength of current class             */
157         s4 interfacetablelength;      /* interface table length                   */
158         vftbl_t *v;                   /* vftbl of current class                   */
159         s4 i;                         /* interface/method/field counter           */
160         arraydescriptor *arraydesc;   /* descriptor for array classes             */
161
162         /* maybe the class is already linked */
163         if (c->linked)
164                 return c;
165
166         /* maybe the class is not loaded */
167         if (!c->loaded)
168 /*              if (!class_load(c)) */
169 /*                      return NULL; */
170                 panic("class_link_intern: class not loaded");
171
172         if (linkverbose)
173                 log_message_class("Linking class: ", c);
174
175         /* ok, this class is somewhat linked */
176         c->linked = true;
177
178         arraydesc = NULL;
179
180         /* check interfaces */
181
182         for (i = 0; i < c->interfacescount; i++) {
183                 tc = c->interfaces[i];
184
185                 /* detect circularity */
186
187                 if (tc == c) {
188                         *exceptionptr =
189                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
190                                                                                  c->name);
191                         return NULL;
192                 }
193
194                 if (!tc->loaded)
195                         if (!class_load_extern(c, tc))
196                                 return NULL;
197
198                 if (!(tc->flags & ACC_INTERFACE)) {
199                         *exceptionptr =
200                                 new_exception_message(string_java_lang_IncompatibleClassChangeError,
201                                                                           "Implementing class");
202                         return NULL;
203                 }
204
205                 if (!tc->linked)
206                         if (!class_link(tc))
207                                 return NULL;
208         }
209         
210         /* check super class */
211
212         super = c->super;
213
214         if (super == NULL) {          /* class java.lang.Object */
215                 c->index = 0;
216         c->classUsed = USED;     /* Object class is always used CO-RT*/
217                 c->impldBy = NULL;
218                 c->instancesize = sizeof(java_objectheader);
219                 
220                 vftbllength = supervftbllength = 0;
221
222                 c->finalizer = NULL;
223
224         } else {
225                 /* detect circularity */
226                 if (super == c) {
227                         *exceptionptr =
228                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
229                                                                                  c->name);
230                         return NULL;
231                 }
232
233                 if (!super->loaded)
234                         if (!class_load_extern(c, super))
235                                 return NULL;
236
237                 if (super->flags & ACC_INTERFACE) {
238                         /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
239                         panic("Interface specified as super class");
240                 }
241
242                 /* Don't allow extending final classes */
243                 if (super->flags & ACC_FINAL) {
244                         *exceptionptr =
245                                 new_exception_message(string_java_lang_VerifyError,
246                                                                           "Cannot inherit from final class");
247                         return NULL;
248                 }
249                 
250                 if (!super->linked)
251                         if (!class_link(super))
252                                 return NULL;
253
254                 /* handle array classes */
255                 if (c->name->text[0] == '[')
256                         if (!(arraydesc = link_array(c)))
257                                 return NULL;
258
259                 if (c->flags & ACC_INTERFACE)
260                         c->index = interfaceindex++;
261                 else
262                         c->index = super->index + 1;
263                 
264                 c->instancesize = super->instancesize;
265                 
266                 vftbllength = supervftbllength = super->vftbl->vftbllength;
267                 
268                 c->finalizer = super->finalizer;
269         }
270
271
272         /* compute vftbl length */
273
274         for (i = 0; i < c->methodscount; i++) {
275                 methodinfo *m = &(c->methods[i]);
276
277                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
278                         tc = super;
279
280                         while (tc) {
281                                 s4 j;
282
283                                 for (j = 0; j < tc->methodscount; j++) {
284                                         if (method_canoverwrite(m, &(tc->methods[j]))) {
285                                                 if (tc->methods[j].flags & ACC_PRIVATE)
286                                                         goto notfoundvftblindex;
287
288                                                 if (tc->methods[j].flags & ACC_FINAL) {
289                                                         /* class a overrides final method . */
290                                                         *exceptionptr =
291                                                                 new_exception(string_java_lang_VerifyError);
292                                                         return NULL;
293                                                 }
294
295                                                 m->vftblindex = tc->methods[j].vftblindex;
296                                                 goto foundvftblindex;
297                                         }
298                                 }
299
300                                 tc = tc->super;
301                         }
302
303                 notfoundvftblindex:
304                         m->vftblindex = (vftbllength++);
305                 foundvftblindex:
306                         ;
307                 }
308         }       
309
310 #if 1
311         /* check interfaces for unimplemented methods in ABSTRACT class */
312
313         if (c->flags & ACC_ABSTRACT) {
314                 classinfo  *ic;
315                 methodinfo *im;
316                 s4 abstractmethodscount;
317                 s4 j;
318                 s4 k;
319
320                 abstractmethodscount = 0;
321
322                 for (i = 0; i < c->interfacescount; i++) {
323                         ic = c->interfaces[i];
324
325                         for (j = 0; j < ic->methodscount; j++) {
326                                 im = &(ic->methods[j]);
327
328                                 tc = c;
329
330                                 while (tc) {
331                                         for (k = 0; k < tc->methodscount; k++) {
332                                                 if (method_canoverwrite(im, &(tc->methods[k])))
333                                                         goto noabstractmethod;
334                                         }
335
336                                         tc = tc->super;
337                                 }
338
339                                 abstractmethodscount++;
340
341                         noabstractmethod:
342                                 ;
343                         }
344                 }
345
346                 if (abstractmethodscount > 0) {
347                         methodinfo *am;
348
349                         /* reallocate methods memory */
350
351                         c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
352                                                                   c->methodscount + abstractmethodscount);
353
354                         for (i = 0; i < c->interfacescount; i++) {
355                                 ic = c->interfaces[i];
356
357                                 for (j = 0; j < ic->methodscount; j++) {
358                                         im = &(ic->methods[j]);
359
360                                         tc = c;
361
362                                         while (tc) {
363                                                 for (k = 0; k < tc->methodscount; k++) {
364                                                         if (method_canoverwrite(im, &(tc->methods[k])))
365                                                                 goto noabstractmethod2;
366                                                 }
367
368                                                 tc = tc->super;
369                                         }
370
371                                         am = &(c->methods[c->methodscount]);
372                                         c->methodscount++;
373
374                                         MCOPY(am, im, methodinfo, 1);
375
376                                         am->vftblindex = (vftbllength++);
377                                         am->class = c;
378
379                                 noabstractmethod2:
380                                         ;
381                                 }
382                         }
383                 }
384         }
385 #endif
386
387 #if defined(STATISTICS)
388         if (opt_stat)
389                 count_vftbl_len +=
390                         sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
391 #endif
392
393         /* compute interfacetable length */
394
395         interfacetablelength = 0;
396         tc = c;
397         while (tc) {
398                 for (i = 0; i < tc->interfacescount; i++) {
399                         s4 h = class_highestinterface(tc->interfaces[i]) + 1;
400                         if (h > interfacetablelength)
401                                 interfacetablelength = h;
402                 }
403                 tc = tc->super;
404         }
405
406         /* allocate virtual function table */
407
408         v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
409                                                           sizeof(methodptr) * (vftbllength - 1) +
410                                                           sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
411         v = (vftbl_t *) (((methodptr *) v) +
412                                          (interfacetablelength - 1) * (interfacetablelength > 1));
413         c->header.vftbl = c->vftbl = v;
414         v->class = c;
415         v->vftbllength = vftbllength;
416         v->interfacetablelength = interfacetablelength;
417         v->arraydesc = arraydesc;
418
419         /* store interface index in vftbl */
420
421         if (c->flags & ACC_INTERFACE)
422                 v->baseval = -(c->index);
423
424         /* copy virtual function table of super class */
425
426         for (i = 0; i < supervftbllength; i++) 
427                 v->table[i] = super->vftbl->table[i];
428         
429         /* add method stubs into virtual function table */
430
431         for (i = 0; i < c->methodscount; i++) {
432                 methodinfo *m = &(c->methods[i]);
433
434 #if 1
435                 if (!m->stubroutine) {
436                         if (!(m->flags & ACC_NATIVE)) {
437                                 m->stubroutine = createcompilerstub(m);
438
439                         } else {
440                                 functionptr f = native_findfunction(c->name,
441                                                                                                         m->name, m->descriptor,
442                                                                                                         (m->flags & ACC_STATIC));
443 #if defined(STATIC_CLASSPATH)
444                                 if (f)
445 #endif
446                                         m->stubroutine = createnativestub(f, m);
447                         }
448                 }
449 #endif
450
451                 if (!(m->flags & ACC_STATIC))
452                         v->table[m->vftblindex] = m->stubroutine;
453         }
454
455         /* compute instance size and offset of each field */
456         
457         for (i = 0; i < c->fieldscount; i++) {
458                 s4 dsize;
459                 fieldinfo *f = &(c->fields[i]);
460                 
461                 if (!(f->flags & ACC_STATIC)) {
462                         dsize = desc_typesize(f->descriptor);
463                         c->instancesize = ALIGN(c->instancesize, dsize);
464                         f->offset = c->instancesize;
465                         c->instancesize += dsize;
466                 }
467         }
468
469         /* initialize interfacetable and interfacevftbllength */
470         
471         v->interfacevftbllength = MNEW(s4, interfacetablelength);
472
473 #if defined(STATISTICS)
474         if (opt_stat)
475                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
476 #endif
477
478         for (i = 0; i < interfacetablelength; i++) {
479                 v->interfacevftbllength[i] = 0;
480                 v->interfacetable[-i] = NULL;
481         }
482         
483         /* add interfaces */
484         
485         for (tc = c; tc != NULL; tc = tc->super)
486                 for (i = 0; i < tc->interfacescount; i++)
487                         linker_addinterface(c, tc->interfaces[i]);
488
489         /* add finalizer method (not for java.lang.Object) */
490
491         if (super) {
492                 methodinfo *fi;
493
494                 fi = class_findmethod(c, utf_finalize, utf_void__void);
495
496                 if (fi)
497                         if (!(fi->flags & ACC_STATIC))
498                                 c->finalizer = fi;
499         }
500
501         /* final tasks */
502
503         linker_compute_subclasses(c);
504
505         if (linkverbose)
506                 log_message_class("Linking done class: ", c);
507
508         /* just return c to show that we didn't had a problem */
509
510         return c;
511 }
512
513
514 /* link_array ******************************************************************
515
516    This function is called by link_class to create the arraydescriptor
517    for an array class.
518
519    This function returns NULL if the array cannot be linked because
520    the component type has not been linked yet.
521
522 *******************************************************************************/
523
524 static arraydescriptor *link_array(classinfo *c)
525 {
526         classinfo *comp = NULL;
527         s4 namelen = c->name->blength;
528         arraydescriptor *desc;
529         vftbl_t *compvftbl;
530
531         /* Check the component type */
532         switch (c->name->text[1]) {
533         case '[':
534                 /* c is an array of arrays. */
535                 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
536                 if (!comp)
537                         panic("Could not find component array class.");
538                 break;
539
540         case 'L':
541                 /* c is an array of objects. */
542                 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
543                 if (!comp)
544                         panic("Could not find component class.");
545                 break;
546         }
547
548         /* If the component type has not been linked, link it now */
549         if (comp && !comp->linked) {
550                 if (!comp->loaded)
551                         if (!class_load_extern(c, comp))
552                                 return NULL;
553
554                 if (!class_link(comp))
555                         return NULL;
556         }
557
558         /* Allocate the arraydescriptor */
559         desc = NEW(arraydescriptor);
560
561         if (comp) {
562                 /* c is an array of references */
563                 desc->arraytype = ARRAYTYPE_OBJECT;
564                 desc->componentsize = sizeof(void*);
565                 desc->dataoffset = OFFSET(java_objectarray, data);
566                 
567                 compvftbl = comp->vftbl;
568                 if (!compvftbl)
569                         panic("Component class has no vftbl");
570                 desc->componentvftbl = compvftbl;
571                 
572                 if (compvftbl->arraydesc) {
573                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
574                         if (compvftbl->arraydesc->dimension >= 255)
575                                 panic("Creating array of dimension >255");
576                         desc->dimension = compvftbl->arraydesc->dimension + 1;
577                         desc->elementtype = compvftbl->arraydesc->elementtype;
578
579                 } else {
580                         desc->elementvftbl = compvftbl;
581                         desc->dimension = 1;
582                         desc->elementtype = ARRAYTYPE_OBJECT;
583                 }
584
585         } else {
586                 /* c is an array of a primitive type */
587                 switch (c->name->text[1]) {
588                 case 'Z':
589                         desc->arraytype = ARRAYTYPE_BOOLEAN;
590                         desc->dataoffset = OFFSET(java_booleanarray,data);
591                         desc->componentsize = sizeof(u1);
592                         break;
593
594                 case 'B':
595                         desc->arraytype = ARRAYTYPE_BYTE;
596                         desc->dataoffset = OFFSET(java_bytearray,data);
597                         desc->componentsize = sizeof(u1);
598                         break;
599
600                 case 'C':
601                         desc->arraytype = ARRAYTYPE_CHAR;
602                         desc->dataoffset = OFFSET(java_chararray,data);
603                         desc->componentsize = sizeof(u2);
604                         break;
605
606                 case 'D':
607                         desc->arraytype = ARRAYTYPE_DOUBLE;
608                         desc->dataoffset = OFFSET(java_doublearray,data);
609                         desc->componentsize = sizeof(double);
610                         break;
611
612                 case 'F':
613                         desc->arraytype = ARRAYTYPE_FLOAT;
614                         desc->dataoffset = OFFSET(java_floatarray,data);
615                         desc->componentsize = sizeof(float);
616                         break;
617
618                 case 'I':
619                         desc->arraytype = ARRAYTYPE_INT;
620                         desc->dataoffset = OFFSET(java_intarray,data);
621                         desc->componentsize = sizeof(s4);
622                         break;
623
624                 case 'J':
625                         desc->arraytype = ARRAYTYPE_LONG;
626                         desc->dataoffset = OFFSET(java_longarray,data);
627                         desc->componentsize = sizeof(s8);
628                         break;
629
630                 case 'S':
631                         desc->arraytype = ARRAYTYPE_SHORT;
632                         desc->dataoffset = OFFSET(java_shortarray,data);
633                         desc->componentsize = sizeof(s2);
634                         break;
635
636                 default:
637                         panic("Invalid array class name");
638                 }
639                 
640                 desc->componentvftbl = NULL;
641                 desc->elementvftbl = NULL;
642                 desc->dimension = 1;
643                 desc->elementtype = desc->arraytype;
644         }
645
646         return desc;
647 }
648
649
650 /* linker_compute_subclasses ***************************************************
651
652    XXX
653
654 *******************************************************************************/
655
656 static void linker_compute_subclasses(classinfo *c)
657 {
658 #if defined(USE_THREADS)
659 #if defined(NATIVE_THREADS)
660         compiler_lock();
661 #else
662         intsDisable();
663 #endif
664 #endif
665
666         if (!(c->flags & ACC_INTERFACE)) {
667                 c->nextsub = 0;
668                 c->sub = 0;
669         }
670
671         if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
672                 c->nextsub = c->super->sub;
673                 c->super->sub = c;
674         }
675
676         classvalue = 0;
677
678         /* this is the java.lang.Object special case */
679
680         if (!class_java_lang_Object) {
681                 linker_compute_class_values(c);
682
683         } else {
684                 linker_compute_class_values(class_java_lang_Object);
685         }
686
687 #if defined(USE_THREADS)
688 #if defined(NATIVE_THREADS)
689         compiler_unlock();
690 #else
691         intsRestore();
692 #endif
693 #endif
694 }
695
696
697 /* linker_compute_class_values *************************************************
698
699    XXX
700
701 *******************************************************************************/
702
703 static void linker_compute_class_values(classinfo *c)
704 {
705         classinfo *subs;
706
707         c->vftbl->baseval = ++classvalue;
708
709         subs = c->sub;
710
711         while (subs) {
712                 linker_compute_class_values(subs);
713
714                 subs = subs->nextsub;
715         }
716
717         c->vftbl->diffval = classvalue - c->vftbl->baseval;
718 }
719
720
721 /* linker_addinterface *********************************************************
722
723    Is needed by link_class for adding a VTBL to a class. All
724    interfaces implemented by ic are added as well.
725
726 *******************************************************************************/
727
728 static void linker_addinterface(classinfo *c, classinfo *ic)
729 {
730         s4     j, m;
731         s4     i   = ic->index;
732         vftbl_t *v = c->vftbl;
733
734         if (i >= v->interfacetablelength)
735                 panic ("Inernal error: interfacetable overflow");
736
737         if (v->interfacetable[-i])
738                 return;
739
740         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
741                 v->interfacevftbllength[i] = 1;
742                 v->interfacetable[-i] = MNEW(methodptr, 1);
743                 v->interfacetable[-i][0] = NULL;
744
745         } else {
746                 v->interfacevftbllength[i] = ic->methodscount;
747                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
748
749 #if defined(STATISTICS)
750                 if (opt_stat)
751                         count_vftbl_len += sizeof(methodptr) *
752                                 (ic->methodscount + (ic->methodscount == 0));
753 #endif
754
755                 for (j = 0; j < ic->methodscount; j++) {
756                         classinfo *sc = c;
757
758                         while (sc) {
759                                 for (m = 0; m < sc->methodscount; m++) {
760                                         methodinfo *mi = &(sc->methods[m]);
761
762                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
763                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
764                                                 goto foundmethod;
765                                         }
766                                 }
767                                 sc = sc->super;
768                         }
769                 foundmethod:
770                         ;
771                 }
772         }
773
774         for (j = 0; j < ic->interfacescount; j++) 
775                 linker_addinterface(c, ic->interfaces[j]);
776 }
777
778
779 /* class_highestinterface ******************************************************
780
781    Used by the function link_class to determine the amount of memory
782    needed for the interface table.
783
784 *******************************************************************************/
785
786 static s4 class_highestinterface(classinfo *c)
787 {
788         s4 h;
789         s4 h2;
790         s4 i;
791         
792     /* check for ACC_INTERFACE bit already done in class_link_intern */
793
794     h = c->index;
795
796         for (i = 0; i < c->interfacescount; i++) {
797                 h2 = class_highestinterface(c->interfaces[i]);
798
799                 if (h2 > h)
800                         h = h2;
801         }
802
803         return h;
804 }
805
806
807 /*
808  * These are local overrides for various environment variables in Emacs.
809  * Please do not remove this and leave it at the end of the file, where
810  * Emacs will automagically detect them.
811  * ---------------------------------------------------------------------
812  * Local variables:
813  * mode: c
814  * indent-tabs-mode: t
815  * c-basic-offset: 4
816  * tab-width: 4
817  * End:
818  */