* src/vm/options.h, src/vm/options.c (getloadingtime): Renamed to
[cacao.git] / src / vm / linker.c
1 /* src/vm/linker.c - class linker functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
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 4834 2006-04-25 12:25:43Z edwin $
36
37 */
38
39
40 #include "config.h"
41
42 #include <assert.h>
43
44 #include "vm/types.h"
45
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
49 #include "vm/class.h"
50 #include "vm/classcache.h"
51 #include "vm/exceptions.h"
52 #include "vm/loader.h"
53 #include "vm/options.h"
54 #include "vm/resolve.h"
55 #include "vm/statistics.h"
56 #include "vm/stringlocal.h"
57 #include "vm/access.h"
58 #include "vm/rt-timing.h"
59
60
61 /* global variables ***********************************************************/
62
63 static s4 interfaceindex;       /* sequential numbering of interfaces         */
64 static s4 classvalue;
65
66
67 /* primitivetype_table *********************************************************
68
69    Structure for primitive classes: contains the class for wrapping
70    the primitive type, the primitive class, the name of the class for
71    wrapping, the one character type signature and the name of the
72    primitive class.
73  
74    CAUTION: Don't change the order of the types. This table is indexed
75    by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
76
77 *******************************************************************************/
78
79 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
80         { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
81         { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
82         { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
83         { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
84         { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
85         { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
86         { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
87         { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
88         { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
89         { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
90         { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }
91 };
92
93
94 /* private functions **********************************************************/
95
96 static bool link_primitivetype_table(void);
97 static classinfo *link_class_intern(classinfo *c);
98 static arraydescriptor *link_array(classinfo *c);
99 static void linker_compute_class_values(classinfo *c);
100 static void linker_compute_subclasses(classinfo *c);
101 static bool linker_addinterface(classinfo *c, classinfo *ic);
102 static s4 class_highestinterface(classinfo *c);
103
104
105 /* linker_init *****************************************************************
106
107    Initializes the linker subsystem.
108
109 *******************************************************************************/
110
111 bool linker_init(void)
112 {
113         /* reset interface index */
114
115         interfaceindex = 0;
116
117         /* link java.lang.Class as first class of the system, because we
118        need it's vftbl for all other classes so we can use a class as
119        object */
120
121         if (!link_class(class_java_lang_Class))
122                 return false;
123
124         /* now set the header.vftbl of all classes which were created
125        before java.lang.Class was linked */
126
127         class_postset_header_vftbl();
128
129
130         /* link important system classes */
131
132         if (!link_class(class_java_lang_Object))
133                 return false;
134
135         if (!link_class(class_java_lang_String))
136                 return false;
137
138         if (!link_class(class_java_lang_Cloneable))
139                 return false;
140
141         if (!link_class(class_java_io_Serializable))
142                 return false;
143
144
145         /* link classes for wrapping primitive types */
146
147         if (!link_class(class_java_lang_Void))
148                 return false;
149
150         if (!link_class(class_java_lang_Boolean))
151                 return false;
152
153         if (!link_class(class_java_lang_Byte))
154                 return false;
155
156         if (!link_class(class_java_lang_Character))
157                 return false;
158
159         if (!link_class(class_java_lang_Short))
160                 return false;
161
162         if (!link_class(class_java_lang_Integer))
163                 return false;
164
165         if (!link_class(class_java_lang_Long))
166                 return false;
167
168         if (!link_class(class_java_lang_Float))
169                 return false;
170
171         if (!link_class(class_java_lang_Double))
172                 return false;
173
174
175         /* load some other important classes */
176
177         if (!link_class(class_java_lang_ClassLoader))
178                 return false;
179
180         if (!link_class(class_java_lang_SecurityManager))
181                 return false;
182
183         if (!link_class(class_java_lang_System))
184                 return false;
185
186         if (!link_class(class_java_lang_Thread))
187                 return false;
188
189         if (!link_class(class_java_lang_ThreadGroup))
190                 return false;
191
192         if (!link_class(class_java_lang_VMThread))
193                 return false;
194
195
196         /* some classes which may be used more often */
197
198         if (!link_class(class_java_lang_StackTraceElement))
199                 return false;
200
201         if (!link_class(class_java_lang_reflect_Constructor))
202                 return false;
203
204         if (!link_class(class_java_lang_reflect_Field))
205                 return false;
206
207         if (!link_class(class_java_lang_reflect_Method))
208                 return false;
209
210         if (!link_class(class_java_security_PrivilegedAction))
211                 return false;
212
213         if (!link_class(class_java_util_Vector))
214                 return false;
215
216         if (!link_class(arrayclass_java_lang_Object))
217                 return false;
218
219
220         /* create pseudo classes used by the typechecker */
221
222     /* pseudo class for Arraystubs (extends java.lang.Object) */
223     
224         pseudo_class_Arraystub =
225                 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
226         pseudo_class_Arraystub->state |= CLASS_LOADED;
227         pseudo_class_Arraystub->super.cls = class_java_lang_Object;
228         pseudo_class_Arraystub->interfacescount = 2;
229         pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
230         pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
231         pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
232
233         if (!classcache_store_unique(pseudo_class_Arraystub)) {
234                 log_text("could not cache pseudo_class_Arraystub");
235                 assert(0);
236         }
237
238         if (!link_class(pseudo_class_Arraystub))
239                 return false;
240
241         /* pseudo class representing the null type */
242
243         pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
244         pseudo_class_Null->state |= CLASS_LOADED;
245         pseudo_class_Null->super.cls = class_java_lang_Object;
246
247         if (!classcache_store_unique(pseudo_class_Null)) {
248                 log_text("could not cache pseudo_class_Null");
249                 assert(0);
250         }
251
252         if (!link_class(pseudo_class_Null))
253                 return false;
254
255         /* pseudo class representing new uninitialized objects */
256     
257         pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
258         pseudo_class_New->state |= CLASS_LOADED;
259         pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
260         pseudo_class_New->super.cls = class_java_lang_Object;
261
262         if (!classcache_store_unique(pseudo_class_New)) {
263                 log_text("could not cache pseudo_class_New");
264                 assert(0);
265         }
266
267         /* create classes representing primitive types */
268
269         if (!link_primitivetype_table())
270                 return false;
271
272
273         /* Correct vftbl-entries (retarded loading and linking of class           */
274         /* java/lang/String).                                                     */
275
276         stringtable_update();
277
278         return true;
279 }
280
281
282 /* link_primitivetype_table ****************************************************
283
284    Create classes representing primitive types.
285
286 *******************************************************************************/
287
288 static bool link_primitivetype_table(void)
289 {  
290         classinfo *c;
291         utf       *u;
292         s4         i;
293
294         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
295                 /* skip dummies */
296
297                 if (!primitivetype_table[i].name)
298                         continue;
299                 
300                 /* create primitive class */
301
302                 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
303
304                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
305                 
306                 /* prevent loader from loading primitive class */
307
308                 c->state |= CLASS_LOADED;
309
310                 /* INFO: don't put primitive classes into the classcache */
311
312                 if (!link_class(c))
313                         return false;
314
315                 primitivetype_table[i].class_primitive = c;
316
317                 /* create class for wrapping the primitive type */
318
319                 u = utf_new_char(primitivetype_table[i].wrapname);
320
321                 if (!(c = load_class_bootstrap(u)))
322                         return false;
323
324                 primitivetype_table[i].class_wrap = c;
325
326                 /* create the primitive array class */
327
328                 if (primitivetype_table[i].arrayname) {
329                         u = utf_new_char(primitivetype_table[i].arrayname);
330                         c = class_create_classinfo(u);
331                         c = load_newly_created_array(c, NULL);
332                         if (c == NULL)
333                                 return false;
334
335                         primitivetype_table[i].arrayclass = c;
336
337                         assert(c->state & CLASS_LOADED);
338
339                         if (!(c->state & CLASS_LINKED))
340                                 if (!link_class(c))
341                                         return false;
342
343                         primitivetype_table[i].arrayvftbl = c->vftbl;
344                 }
345         }
346
347         return true;
348 }
349
350
351 /* link_class ******************************************************************
352
353    Wrapper function for link_class_intern to ease monitor enter/exit
354    and exception handling.
355
356 *******************************************************************************/
357
358 classinfo *link_class(classinfo *c)
359 {
360         classinfo *r;
361 #if defined(ENABLE_RT_TIMING)
362         struct timespec time_start, time_end;
363 #endif
364
365         RT_TIMING_GET_TIME(time_start);
366
367         if (!c) {
368                 exceptions_throw_nullpointerexception();
369                 return NULL;
370         }
371
372 #if defined(USE_THREADS)
373         /* enter a monitor on the class */
374
375         builtin_monitorenter((java_objectheader *) c);
376 #endif
377
378         /* maybe the class is already linked */
379
380         if (c->state & CLASS_LINKED) {
381 #if defined(USE_THREADS)
382                 builtin_monitorexit((java_objectheader *) c);
383 #endif
384
385                 return c;
386         }
387
388 #if defined(ENABLE_STATISTICS)
389         /* measure time */
390
391         if (opt_getcompilingtime)
392                 compilingtime_stop();
393
394         if (opt_getloadingtime)
395                 loadingtime_start();
396 #endif
397
398         /* call the internal function */
399
400         r = link_class_intern(c);
401
402         /* if return value is NULL, we had a problem and the class is not linked */
403
404         if (!r)
405                 c->state &= ~CLASS_LINKING;
406
407 #if defined(ENABLE_STATISTICS)
408         /* measure time */
409
410         if (opt_getloadingtime)
411                 loadingtime_stop();
412
413         if (opt_getcompilingtime)
414                 compilingtime_start();
415 #endif
416
417 #if defined(USE_THREADS)
418         /* leave the monitor */
419
420         builtin_monitorexit((java_objectheader *) c);
421 #endif
422
423         RT_TIMING_GET_TIME(time_end);
424
425         RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
426
427         return r;
428 }
429
430
431 /* link_class_intern ***********************************************************
432
433    Tries to link a class. The function calculates the length in bytes
434    that an instance of this class requires as well as the VTBL for
435    methods and interface methods.
436         
437 *******************************************************************************/
438
439 static classinfo *link_class_intern(classinfo *c)
440 {
441         classinfo *super;             /* super class                              */
442         classinfo *tc;                /* temporary class variable                 */
443         s4 supervftbllength;          /* vftbllegnth of super class               */
444         s4 vftbllength;               /* vftbllength of current class             */
445         s4 interfacetablelength;      /* interface table length                   */
446         vftbl_t *v;                   /* vftbl of current class                   */
447         s4 i,j;                       /* interface/method/field counter           */
448         arraydescriptor *arraydesc;   /* descriptor for array classes             */
449 #if defined(ENABLE_RT_TIMING)
450         struct timespec time_start, time_resolving, time_compute_vftbl,
451                                         time_abstract, time_compute_iftbl, time_fill_vftbl,
452                                         time_offsets, time_fill_iftbl, time_finalizer,
453                                         time_exceptions, time_subclasses;
454 #endif
455
456         RT_TIMING_GET_TIME(time_start);
457
458         /* the class is already linked */
459
460         if (c->state & CLASS_LINKED)
461                 return c;
462
463 #if !defined(NDEBUG)
464         if (linkverbose)
465                 log_message_class("Linking class: ", c);
466 #endif
467
468         /* the class must be loaded */
469
470         /* XXX should this be a specific exception? */
471         assert(c->state & CLASS_LOADED);
472
473         /* cache the self-reference of this class                          */
474         /* we do this for cases where the defining loader of the class     */
475         /* has not yet been recorded as an initiating loader for the class */
476         /* this is needed so subsequent code can assume that self-refs     */
477         /* will always resolve lazily                                      */
478         /* No need to do it for the bootloader - it is always registered   */
479         /* as initiating loader for the classes it loads.                  */
480         if (c->classloader)
481                 classcache_store(c->classloader,c,false);
482
483         /* this class is currently linking */
484
485         c->state |= CLASS_LINKING;
486
487         arraydesc = NULL;
488
489         /* check interfaces */
490
491         for (i = 0; i < c->interfacescount; i++) {
492                 /* resolve this super interface */
493
494                 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
495                                                                                    true, false, &tc))
496                         return NULL;
497
498                 c->interfaces[i].cls = tc;
499                 
500                 /* detect circularity */
501
502                 if (tc == c) {
503                         *exceptionptr =
504                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
505                                                                                  c->name);
506                         return NULL;
507                 }
508
509                 assert(tc->state & CLASS_LOADED);
510
511                 if (!(tc->flags & ACC_INTERFACE)) {
512                         *exceptionptr =
513                                 new_exception_message(string_java_lang_IncompatibleClassChangeError,
514                                                                           "Implementing class");
515                         return NULL;
516                 }
517
518                 if (!(tc->state & CLASS_LINKED))
519                         if (!link_class(tc))
520                                 return NULL;
521         }
522         
523         /* check super class */
524
525         super = NULL;
526
527         if (c->super.any == NULL) {                     /* class java.lang.Object */
528                 c->index = 0;
529                 c->instancesize = sizeof(java_objectheader);
530                 
531                 vftbllength = supervftbllength = 0;
532
533                 c->finalizer = NULL;
534
535         } else {
536                 /* resolve super class */
537
538                 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
539                                                                                    &super))
540                         return NULL;
541                 c->super.cls = super;
542                 
543                 /* detect circularity */
544
545                 if (super == c) {
546                         *exceptionptr =
547                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
548                                                                                  c->name);
549                         return NULL;
550                 }
551
552                 assert(super->state & CLASS_LOADED);
553
554                 if (super->flags & ACC_INTERFACE) {
555                         /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
556                         log_text("Interface specified as super class");
557                         assert(0);
558                 }
559
560                 /* Don't allow extending final classes */
561
562                 if (super->flags & ACC_FINAL) {
563                         *exceptionptr =
564                                 new_exception_message(string_java_lang_VerifyError,
565                                                                           "Cannot inherit from final class");
566                         return NULL;
567                 }
568
569                 /* link the superclass if necessary */
570                 
571                 if (!(super->state & CLASS_LINKED))
572                         if (!link_class(super))
573                                 return NULL;
574
575                 /* OR the ACC_CLASS_HAS_POINTERS flag */
576
577                 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
578
579                 /* handle array classes */
580
581                 if (c->name->text[0] == '[')
582                         if (!(arraydesc = link_array(c)))
583                                 return NULL;
584
585                 if (c->flags & ACC_INTERFACE)
586                         c->index = interfaceindex++;
587                 else
588                         c->index = super->index + 1;
589                 
590                 c->instancesize = super->instancesize;
591
592                 vftbllength = supervftbllength = super->vftbl->vftbllength;
593                 
594                 c->finalizer = super->finalizer;
595         }
596         RT_TIMING_GET_TIME(time_resolving);
597
598
599         /* compute vftbl length */
600
601         for (i = 0; i < c->methodscount; i++) {
602                 methodinfo *m = &(c->methods[i]);
603
604                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
605                         tc = super;
606
607                         while (tc) {
608                                 s4 j;
609
610                                 for (j = 0; j < tc->methodscount; j++) {
611                                         if (method_canoverwrite(m, &(tc->methods[j]))) {
612                                                 if (tc->methods[j].flags & ACC_PRIVATE)
613                                                         goto notfoundvftblindex;
614
615                                                 /* package-private methods in other packages */
616                                                 /* must not be overridden                    */
617                                                 /* (see Java Language Specification 8.4.8.1) */
618                                                 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
619                                                          && !SAME_PACKAGE(c,tc) ) 
620                                                 {
621                                                     goto notfoundvftblindex;
622                                                 }
623
624                                                 if (tc->methods[j].flags & ACC_FINAL) {
625                                                         /* class a overrides final method . */
626                                                         *exceptionptr =
627                                                                 new_exception(string_java_lang_VerifyError);
628                                                         return NULL;
629                                                 }
630
631                                                 /* method m overwrites method j of class tc */
632
633 #if defined(ENABLE_VERIFIER)
634                                                 /* Add loading constraints (for the more general    */
635                                                 /* types of method tc->methods[j]). --              */
636                                                 /* Not for <init>,  as it is not invoked virtually. */
637                                                 if ((m->name != utf_init)
638                                                         && !classcache_add_constraints_for_params(
639                                                                         c->classloader, tc->classloader,
640                                                                         &(tc->methods[j])))
641                                                 {
642                                                         return NULL;
643                                                 }
644 #endif
645
646                                                 m->vftblindex = tc->methods[j].vftblindex;
647                                                 goto foundvftblindex;
648                                         }
649                                 }
650
651                                 tc = tc->super.cls;
652                         }
653
654                 notfoundvftblindex:
655                         m->vftblindex = (vftbllength++);
656                 foundvftblindex:
657                         ;
658                 }
659         }
660         RT_TIMING_GET_TIME(time_compute_vftbl);
661
662
663         /* Check all interfaces of an abtract class (maybe be an interface
664            too) for unimplemented methods.  Such methods are called
665            miranda-methods and are marked with the ACC_MIRANDA flag.
666            VMClass.getDeclaredMethods does not return such methods. */
667
668         if (c->flags & ACC_ABSTRACT) {
669                 classinfo  *ic;
670                 methodinfo *im;
671                 s4 abstractmethodscount;
672                 s4 j;
673                 s4 k;
674
675                 abstractmethodscount = 0;
676
677                 /* check all interfaces of the abtract class */
678
679                 for (i = 0; i < c->interfacescount; i++) {
680                         ic = c->interfaces[i].cls;
681
682                         for (j = 0; j < ic->methodscount; j++) {
683                                 im = &(ic->methods[j]);
684
685                                 /* skip `<clinit>' and `<init>' */
686
687                                 if ((im->name == utf_clinit) || (im->name == utf_init))
688                                         continue;
689
690                                 for (tc = c; tc != NULL; tc = tc->super.cls) {
691                                         for (k = 0; k < tc->methodscount; k++) {
692                                                 if (method_canoverwrite(im, &(tc->methods[k])))
693                                                         goto noabstractmethod;
694                                         }
695                                 }
696
697                                 abstractmethodscount++;
698
699                         noabstractmethod:
700                                 ;
701                         }
702                 }
703
704                 if (abstractmethodscount > 0) {
705                         methodinfo *am;
706
707                         /* reallocate methods memory */
708
709                         c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
710                                                                   c->methodscount + abstractmethodscount);
711
712                         for (i = 0; i < c->interfacescount; i++) {
713                                 ic = c->interfaces[i].cls;
714
715                                 for (j = 0; j < ic->methodscount; j++) {
716                                         im = &(ic->methods[j]);
717
718                                         /* skip `<clinit>' and `<init>' */
719
720                                         if ((im->name == utf_clinit) || (im->name == utf_init))
721                                                 continue;
722
723                                         for (tc = c; tc != NULL; tc = tc->super.cls) {
724                                                 for (k = 0; k < tc->methodscount; k++) {
725                                                         if (method_canoverwrite(im, &(tc->methods[k])))
726                                                                 goto noabstractmethod2;
727                                                 }
728                                         }
729
730                                         /* Copy the method found into the new c->methods
731                                            array and tag it as miranda-method. */
732
733                                         am = &(c->methods[c->methodscount]);
734                                         c->methodscount++;
735
736                                         MCOPY(am, im, methodinfo, 1);
737
738                                         am->vftblindex  = (vftbllength++);
739                                         am->class       = c;
740                                         am->flags      |= ACC_MIRANDA;
741
742                                 noabstractmethod2:
743                                         ;
744                                 }
745                         }
746                 }
747         }
748         RT_TIMING_GET_TIME(time_abstract);
749
750
751 #if defined(ENABLE_STATISTICS)
752         if (opt_stat)
753                 count_vftbl_len +=
754                         sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
755 #endif
756
757         /* compute interfacetable length */
758
759         interfacetablelength = 0;
760         tc = c;
761         while (tc) {
762                 for (i = 0; i < tc->interfacescount; i++) {
763                         s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
764                         if (h > interfacetablelength)
765                                 interfacetablelength = h;
766                 }
767                 tc = tc->super.cls;
768         }
769         RT_TIMING_GET_TIME(time_compute_iftbl);
770
771         /* allocate virtual function table */
772
773         v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
774                                                           sizeof(methodptr) * (vftbllength - 1) +
775                                                           sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
776         v = (vftbl_t *) (((methodptr *) v) +
777                                          (interfacetablelength - 1) * (interfacetablelength > 1));
778         c->vftbl = v;
779         v->class = c;
780         v->vftbllength = vftbllength;
781         v->interfacetablelength = interfacetablelength;
782         v->arraydesc = arraydesc;
783
784         /* store interface index in vftbl */
785
786         if (c->flags & ACC_INTERFACE)
787                 v->baseval = -(c->index);
788
789         /* copy virtual function table of super class */
790
791         for (i = 0; i < supervftbllength; i++) 
792                 v->table[i] = super->vftbl->table[i];
793         
794         /* add method stubs into virtual function table */
795
796         for (i = 0; i < c->methodscount; i++) {
797                 methodinfo *m = &(c->methods[i]);
798
799                 /* Methods in ABSTRACT classes from interfaces maybe already
800                    have a stubroutine. */
801
802                 if (!m->stubroutine) {
803 #if defined(ENABLE_JIT)
804 # if defined(ENABLE_INTRP)
805                         if (opt_intrp)
806                                 m->stubroutine = intrp_createcompilerstub(m);
807                         else
808 #endif
809                                 m->stubroutine = createcompilerstub(m);
810 #else
811                         m->stubroutine = intrp_createcompilerstub(m);
812 #endif
813                 }
814
815                 if (!(m->flags & ACC_STATIC))
816                         v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
817         }
818         RT_TIMING_GET_TIME(time_fill_vftbl);
819
820         /* compute instance size and offset of each field */
821         
822         for (i = 0; i < c->fieldscount; i++) {
823                 s4 dsize;
824                 fieldinfo *f = &(c->fields[i]);
825                 
826                 if (!(f->flags & ACC_STATIC)) {
827                         dsize = descriptor_typesize(f->parseddesc);
828                         c->instancesize = ALIGN(c->instancesize, dsize);
829                         f->offset = c->instancesize;
830                         c->instancesize += dsize;
831                 }
832         }
833         RT_TIMING_GET_TIME(time_offsets);
834
835         /* initialize interfacetable and interfacevftbllength */
836
837         v->interfacevftbllength = MNEW(s4, interfacetablelength);
838
839 #if defined(ENABLE_STATISTICS)
840         if (opt_stat)
841                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
842 #endif
843
844         for (i = 0; i < interfacetablelength; i++) {
845                 v->interfacevftbllength[i] = 0;
846                 v->interfacetable[-i] = NULL;
847         }
848
849         /* add interfaces */
850
851         for (tc = c; tc != NULL; tc = tc->super.cls)
852                 for (i = 0; i < tc->interfacescount; i++)
853                         if (!linker_addinterface(c, tc->interfaces[i].cls))
854                                 return NULL;
855
856         RT_TIMING_GET_TIME(time_fill_iftbl);
857
858         /* add finalizer method (not for java.lang.Object) */
859
860         if (super) {
861                 methodinfo *fi;
862
863                 fi = class_findmethod(c, utf_finalize, utf_void__void);
864
865                 if (fi)
866                         if (!(fi->flags & ACC_STATIC))
867                                 c->finalizer = fi;
868         }
869         RT_TIMING_GET_TIME(time_finalizer);
870
871         /* resolve exception class references */
872
873         for (i = 0; i < c->methodscount; i++) {
874                 methodinfo *m = &(c->methods[i]);
875
876                 for (j = 0; j < m->exceptiontablelength; j++) {
877                         if (!m->exceptiontable[j].catchtype.any)
878                                 continue;
879                         if (!resolve_classref_or_classinfo(NULL,
880                                                                                            m->exceptiontable[j].catchtype,
881                                                                                            resolveEager, true, false,
882                                                                                            &(m->exceptiontable[j].catchtype.cls)))
883                                 return NULL;
884                 }
885         }
886         RT_TIMING_GET_TIME(time_exceptions);
887         
888         /* final tasks */
889
890         linker_compute_subclasses(c);
891
892         RT_TIMING_GET_TIME(time_subclasses);
893
894         /* revert the linking state and class is linked */
895
896         c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
897
898 #if !defined(NDEBUG)
899         if (linkverbose)
900                 log_message_class("Linking done class: ", c);
901 #endif
902
903         RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
904         RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
905         RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
906         RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
907         RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
908         RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
909         RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
910         RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
911         RT_TIMING_TIME_DIFF(time_finalizer    ,time_exceptions   ,RT_TIMING_LINK_EXCEPTS);
912         RT_TIMING_TIME_DIFF(time_exceptions   ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
913
914         /* just return c to show that we didn't had a problem */
915
916         return c;
917 }
918
919
920 /* link_array ******************************************************************
921
922    This function is called by link_class to create the arraydescriptor
923    for an array class.
924
925    This function returns NULL if the array cannot be linked because
926    the component type has not been linked yet.
927
928 *******************************************************************************/
929
930 static arraydescriptor *link_array(classinfo *c)
931 {
932         classinfo       *comp;
933         s4               namelen;
934         arraydescriptor *desc;
935         vftbl_t         *compvftbl;
936         utf             *u;
937
938         comp = NULL;
939         namelen = c->name->blength;
940
941         /* Check the component type */
942
943         switch (c->name->text[1]) {
944         case '[':
945                 /* c is an array of arrays. */
946                 u = utf_new(c->name->text + 1, namelen - 1);
947                 if (!(comp = load_class_from_classloader(u, c->classloader)))
948                         return NULL;
949                 break;
950
951         case 'L':
952                 /* c is an array of objects. */
953                 u = utf_new(c->name->text + 2, namelen - 3);
954                 if (!(comp = load_class_from_classloader(u, c->classloader)))
955                         return NULL;
956                 break;
957         }
958
959         /* If the component type has not been linked, link it now */
960
961         assert(!comp || (comp->state & CLASS_LOADED));
962
963         if (comp && !(comp->state & CLASS_LINKED))
964                 if (!link_class(comp))
965                         return NULL;
966
967         /* Allocate the arraydescriptor */
968
969         desc = NEW(arraydescriptor);
970
971         if (comp) {
972                 /* c is an array of references */
973                 desc->arraytype = ARRAYTYPE_OBJECT;
974                 desc->componentsize = sizeof(void*);
975                 desc->dataoffset = OFFSET(java_objectarray, data);
976                 
977                 compvftbl = comp->vftbl;
978
979                 if (!compvftbl) {
980                         log_text("Component class has no vftbl");
981                         assert(0);
982                 }
983
984                 desc->componentvftbl = compvftbl;
985                 
986                 if (compvftbl->arraydesc) {
987                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
988
989                         if (compvftbl->arraydesc->dimension >= 255) {
990                                 log_text("Creating array of dimension >255");
991                                 assert(0);
992                         }
993
994                         desc->dimension = compvftbl->arraydesc->dimension + 1;
995                         desc->elementtype = compvftbl->arraydesc->elementtype;
996
997                 } else {
998                         desc->elementvftbl = compvftbl;
999                         desc->dimension = 1;
1000                         desc->elementtype = ARRAYTYPE_OBJECT;
1001                 }
1002
1003         } else {
1004                 /* c is an array of a primitive type */
1005                 switch (c->name->text[1]) {
1006                 case 'Z':
1007                         desc->arraytype = ARRAYTYPE_BOOLEAN;
1008                         desc->dataoffset = OFFSET(java_booleanarray,data);
1009                         desc->componentsize = sizeof(u1);
1010                         break;
1011
1012                 case 'B':
1013                         desc->arraytype = ARRAYTYPE_BYTE;
1014                         desc->dataoffset = OFFSET(java_bytearray,data);
1015                         desc->componentsize = sizeof(u1);
1016                         break;
1017
1018                 case 'C':
1019                         desc->arraytype = ARRAYTYPE_CHAR;
1020                         desc->dataoffset = OFFSET(java_chararray,data);
1021                         desc->componentsize = sizeof(u2);
1022                         break;
1023
1024                 case 'D':
1025                         desc->arraytype = ARRAYTYPE_DOUBLE;
1026                         desc->dataoffset = OFFSET(java_doublearray,data);
1027                         desc->componentsize = sizeof(double);
1028                         break;
1029
1030                 case 'F':
1031                         desc->arraytype = ARRAYTYPE_FLOAT;
1032                         desc->dataoffset = OFFSET(java_floatarray,data);
1033                         desc->componentsize = sizeof(float);
1034                         break;
1035
1036                 case 'I':
1037                         desc->arraytype = ARRAYTYPE_INT;
1038                         desc->dataoffset = OFFSET(java_intarray,data);
1039                         desc->componentsize = sizeof(s4);
1040                         break;
1041
1042                 case 'J':
1043                         desc->arraytype = ARRAYTYPE_LONG;
1044                         desc->dataoffset = OFFSET(java_longarray,data);
1045                         desc->componentsize = sizeof(s8);
1046                         break;
1047
1048                 case 'S':
1049                         desc->arraytype = ARRAYTYPE_SHORT;
1050                         desc->dataoffset = OFFSET(java_shortarray,data);
1051                         desc->componentsize = sizeof(s2);
1052                         break;
1053
1054                 default:
1055                         *exceptionptr = new_noclassdeffounderror(c->name);
1056                         return NULL;
1057                 }
1058                 
1059                 desc->componentvftbl = NULL;
1060                 desc->elementvftbl = NULL;
1061                 desc->dimension = 1;
1062                 desc->elementtype = desc->arraytype;
1063         }
1064
1065         return desc;
1066 }
1067
1068
1069 /* linker_compute_subclasses ***************************************************
1070
1071    XXX
1072
1073 *******************************************************************************/
1074
1075 static void linker_compute_subclasses(classinfo *c)
1076 {
1077 #if defined(USE_THREADS)
1078 #if defined(NATIVE_THREADS)
1079         compiler_lock();
1080 #else
1081         intsDisable();
1082 #endif
1083 #endif
1084
1085         if (!(c->flags & ACC_INTERFACE)) {
1086                 c->nextsub = 0;
1087                 c->sub = 0;
1088         }
1089
1090         if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1091                 c->nextsub = c->super.cls->sub;
1092                 c->super.cls->sub = c;
1093         }
1094
1095         classvalue = 0;
1096
1097         /* compute class values */
1098
1099         linker_compute_class_values(class_java_lang_Object);
1100
1101 #if defined(USE_THREADS)
1102 #if defined(NATIVE_THREADS)
1103         compiler_unlock();
1104 #else
1105         intsRestore();
1106 #endif
1107 #endif
1108 }
1109
1110
1111 /* linker_compute_class_values *************************************************
1112
1113    XXX
1114
1115 *******************************************************************************/
1116
1117 static void linker_compute_class_values(classinfo *c)
1118 {
1119         classinfo *subs;
1120
1121         c->vftbl->baseval = ++classvalue;
1122
1123         subs = c->sub;
1124
1125         while (subs) {
1126                 linker_compute_class_values(subs);
1127
1128                 subs = subs->nextsub;
1129         }
1130
1131         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1132 }
1133
1134
1135 /* linker_addinterface *********************************************************
1136
1137    Is needed by link_class for adding a VTBL to a class. All
1138    interfaces implemented by ic are added as well.
1139
1140    RETURN VALUE:
1141       true.........everything ok
1142           false........an exception has been thrown
1143
1144 *******************************************************************************/
1145
1146 static bool linker_addinterface(classinfo *c, classinfo *ic)
1147 {
1148         s4     j, m;
1149         s4     i   = ic->index;
1150         vftbl_t *v = c->vftbl;
1151
1152         if (i >= v->interfacetablelength) {
1153                 log_text("Inernal error: interfacetable overflow");
1154                 assert(0);
1155         }
1156
1157         /* if this interface has already been added, return immediately */
1158
1159         if (v->interfacetable[-i])
1160                 return true;
1161
1162         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1163                 v->interfacevftbllength[i] = 1;
1164                 v->interfacetable[-i] = MNEW(methodptr, 1);
1165                 v->interfacetable[-i][0] = NULL;
1166
1167         }
1168         else {
1169                 v->interfacevftbllength[i] = ic->methodscount;
1170                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1171
1172 #if defined(ENABLE_STATISTICS)
1173                 if (opt_stat)
1174                         count_vftbl_len += sizeof(methodptr) *
1175                                 (ic->methodscount + (ic->methodscount == 0));
1176 #endif
1177
1178                 for (j = 0; j < ic->methodscount; j++) {
1179                         classinfo *sc = c;
1180
1181                         while (sc) {
1182                                 for (m = 0; m < sc->methodscount; m++) {
1183                                         methodinfo *mi = &(sc->methods[m]);
1184
1185                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1186                                                 /* method mi overwrites the (abstract) method    */
1187 #if defined(ENABLE_VERIFIER)
1188                                                 /* Add loading constraints (for the more general */
1189                                                 /* types of the method ic->methods[j]).          */
1190                                                 if (!classcache_add_constraints_for_params(
1191                                                                         c->classloader, ic->classloader,
1192                                                                         &(ic->methods[j])))
1193                                                 {
1194                                                         return false;
1195                                                 }
1196 #endif
1197                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1198                                                 goto foundmethod;
1199                                         }
1200                                 }
1201                                 sc = sc->super.cls;
1202                         }
1203                 foundmethod:
1204                         ;
1205                 }
1206         }
1207
1208         /* add superinterfaces of this interface */
1209
1210         for (j = 0; j < ic->interfacescount; j++)
1211                 if (!linker_addinterface(c, ic->interfaces[j].cls))
1212                         return false;
1213
1214         /* everything ok */
1215         return true;
1216 }
1217
1218
1219 /* class_highestinterface ******************************************************
1220
1221    Used by the function link_class to determine the amount of memory
1222    needed for the interface table.
1223
1224 *******************************************************************************/
1225
1226 static s4 class_highestinterface(classinfo *c)
1227 {
1228         s4 h;
1229         s4 h2;
1230         s4 i;
1231         
1232     /* check for ACC_INTERFACE bit already done in link_class_intern */
1233
1234     h = c->index;
1235
1236         for (i = 0; i < c->interfacescount; i++) {
1237                 h2 = class_highestinterface(c->interfaces[i].cls);
1238
1239                 if (h2 > h)
1240                         h = h2;
1241         }
1242
1243         return h;
1244 }
1245
1246
1247 /*
1248  * These are local overrides for various environment variables in Emacs.
1249  * Please do not remove this and leave it at the end of the file, where
1250  * Emacs will automagically detect them.
1251  * ---------------------------------------------------------------------
1252  * Local variables:
1253  * mode: c
1254  * indent-tabs-mode: t
1255  * c-basic-offset: 4
1256  * tab-width: 4
1257  * End:
1258  * vim:noexpandtab:sw=4:ts=4:
1259  */