2dd620df370e0fd564d01bb8df07aea25ddab3c1
[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 4799 2006-04-20 20:38:07Z 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 void 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 (getcompilingtime)
392                 compilingtime_stop();
393
394         if (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 (getloadingtime)
411                 loadingtime_stop();
412
413         if (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                 if (!(super->state & CLASS_LINKED))
570                         if (!link_class(super))
571                                 return NULL;
572
573                 /* handle array classes */
574
575                 if (c->name->text[0] == '[')
576                         if (!(arraydesc = link_array(c)))
577                                 return NULL;
578
579                 if (c->flags & ACC_INTERFACE)
580                         c->index = interfaceindex++;
581                 else
582                         c->index = super->index + 1;
583                 
584                 c->instancesize = super->instancesize;
585                 
586                 vftbllength = supervftbllength = super->vftbl->vftbllength;
587                 
588                 c->finalizer = super->finalizer;
589         }
590         RT_TIMING_GET_TIME(time_resolving);
591
592
593         /* compute vftbl length */
594
595         for (i = 0; i < c->methodscount; i++) {
596                 methodinfo *m = &(c->methods[i]);
597
598                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
599                         tc = super;
600
601                         while (tc) {
602                                 s4 j;
603
604                                 for (j = 0; j < tc->methodscount; j++) {
605                                         if (method_canoverwrite(m, &(tc->methods[j]))) {
606                                                 if (tc->methods[j].flags & ACC_PRIVATE)
607                                                         goto notfoundvftblindex;
608
609                                                 /* package-private methods in other packages */
610                                                 /* must not be overridden                    */
611                                                 /* (see Java Language Specification 8.4.8.1) */
612                                                 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
613                                                          && !SAME_PACKAGE(c,tc) ) 
614                                                 {
615                                                     goto notfoundvftblindex;
616                                                 }
617
618                                                 if (tc->methods[j].flags & ACC_FINAL) {
619                                                         /* class a overrides final method . */
620                                                         *exceptionptr =
621                                                                 new_exception(string_java_lang_VerifyError);
622                                                         return NULL;
623                                                 }
624
625                                                 /* method m overwrites method j of class tc */
626
627                                                 if (!classcache_add_constraints_for_params(
628                                                                         c->classloader, tc->classloader, m))
629                                                         return NULL;
630
631                                                 m->vftblindex = tc->methods[j].vftblindex;
632                                                 goto foundvftblindex;
633                                         }
634                                 }
635
636                                 tc = tc->super.cls;
637                         }
638
639                 notfoundvftblindex:
640                         m->vftblindex = (vftbllength++);
641                 foundvftblindex:
642                         ;
643                 }
644         }
645         RT_TIMING_GET_TIME(time_compute_vftbl);
646
647
648         /* Check all interfaces of an abtract class (maybe be an interface
649            too) for unimplemented methods.  Such methods are called
650            miranda-methods and are marked with the ACC_MIRANDA flag.
651            VMClass.getDeclaredMethods does not return such methods. */
652
653         if (c->flags & ACC_ABSTRACT) {
654                 classinfo  *ic;
655                 methodinfo *im;
656                 s4 abstractmethodscount;
657                 s4 j;
658                 s4 k;
659
660                 abstractmethodscount = 0;
661
662                 /* check all interfaces of the abtract class */
663
664                 for (i = 0; i < c->interfacescount; i++) {
665                         ic = c->interfaces[i].cls;
666
667                         for (j = 0; j < ic->methodscount; j++) {
668                                 im = &(ic->methods[j]);
669
670                                 /* skip `<clinit>' and `<init>' */
671
672                                 if ((im->name == utf_clinit) || (im->name == utf_init))
673                                         continue;
674
675                                 for (tc = c; tc != NULL; tc = tc->super.cls) {
676                                         for (k = 0; k < tc->methodscount; k++) {
677                                                 if (method_canoverwrite(im, &(tc->methods[k])))
678                                                         goto noabstractmethod;
679                                         }
680                                 }
681
682                                 abstractmethodscount++;
683
684                         noabstractmethod:
685                                 ;
686                         }
687                 }
688
689                 if (abstractmethodscount > 0) {
690                         methodinfo *am;
691
692                         /* reallocate methods memory */
693
694                         c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
695                                                                   c->methodscount + abstractmethodscount);
696
697                         for (i = 0; i < c->interfacescount; i++) {
698                                 ic = c->interfaces[i].cls;
699
700                                 for (j = 0; j < ic->methodscount; j++) {
701                                         im = &(ic->methods[j]);
702
703                                         /* skip `<clinit>' and `<init>' */
704
705                                         if ((im->name == utf_clinit) || (im->name == utf_init))
706                                                 continue;
707
708                                         for (tc = c; tc != NULL; tc = tc->super.cls) {
709                                                 for (k = 0; k < tc->methodscount; k++) {
710                                                         if (method_canoverwrite(im, &(tc->methods[k])))
711                                                                 goto noabstractmethod2;
712                                                 }
713                                         }
714
715                                         /* Copy the method found into the new c->methods
716                                            array and tag it as miranda-method. */
717
718                                         am = &(c->methods[c->methodscount]);
719                                         c->methodscount++;
720
721                                         MCOPY(am, im, methodinfo, 1);
722
723                                         am->vftblindex  = (vftbllength++);
724                                         am->class       = c;
725                                         am->flags      |= ACC_MIRANDA;
726
727                                 noabstractmethod2:
728                                         ;
729                                 }
730                         }
731                 }
732         }
733         RT_TIMING_GET_TIME(time_abstract);
734
735
736 #if defined(ENABLE_STATISTICS)
737         if (opt_stat)
738                 count_vftbl_len +=
739                         sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
740 #endif
741
742         /* compute interfacetable length */
743
744         interfacetablelength = 0;
745         tc = c;
746         while (tc) {
747                 for (i = 0; i < tc->interfacescount; i++) {
748                         s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
749                         if (h > interfacetablelength)
750                                 interfacetablelength = h;
751                 }
752                 tc = tc->super.cls;
753         }
754         RT_TIMING_GET_TIME(time_compute_iftbl);
755
756         /* allocate virtual function table */
757
758         v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
759                                                           sizeof(methodptr) * (vftbllength - 1) +
760                                                           sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
761         v = (vftbl_t *) (((methodptr *) v) +
762                                          (interfacetablelength - 1) * (interfacetablelength > 1));
763         c->vftbl = v;
764         v->class = c;
765         v->vftbllength = vftbllength;
766         v->interfacetablelength = interfacetablelength;
767         v->arraydesc = arraydesc;
768
769         /* store interface index in vftbl */
770
771         if (c->flags & ACC_INTERFACE)
772                 v->baseval = -(c->index);
773
774         /* copy virtual function table of super class */
775
776         for (i = 0; i < supervftbllength; i++) 
777                 v->table[i] = super->vftbl->table[i];
778         
779         /* add method stubs into virtual function table */
780
781         for (i = 0; i < c->methodscount; i++) {
782                 methodinfo *m = &(c->methods[i]);
783
784                 /* Methods in ABSTRACT classes from interfaces maybe already
785                    have a stubroutine. */
786
787                 if (!m->stubroutine) {
788 #if defined(ENABLE_JIT)
789 # if defined(ENABLE_INTRP)
790                         if (opt_intrp)
791                                 m->stubroutine = intrp_createcompilerstub(m);
792                         else
793 #endif
794                                 m->stubroutine = createcompilerstub(m);
795 #else
796                         m->stubroutine = intrp_createcompilerstub(m);
797 #endif
798                 }
799
800                 if (!(m->flags & ACC_STATIC))
801                         v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
802         }
803         RT_TIMING_GET_TIME(time_fill_vftbl);
804
805         /* compute instance size and offset of each field */
806         
807         for (i = 0; i < c->fieldscount; i++) {
808                 s4 dsize;
809                 fieldinfo *f = &(c->fields[i]);
810                 
811                 if (!(f->flags & ACC_STATIC)) {
812                         dsize = descriptor_typesize(f->parseddesc);
813                         c->instancesize = ALIGN(c->instancesize, dsize);
814                         f->offset = c->instancesize;
815                         c->instancesize += dsize;
816                 }
817         }
818         RT_TIMING_GET_TIME(time_offsets);
819
820         /* initialize interfacetable and interfacevftbllength */
821         
822         v->interfacevftbllength = MNEW(s4, interfacetablelength);
823
824 #if defined(ENABLE_STATISTICS)
825         if (opt_stat)
826                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
827 #endif
828
829         for (i = 0; i < interfacetablelength; i++) {
830                 v->interfacevftbllength[i] = 0;
831                 v->interfacetable[-i] = NULL;
832         }
833         
834         /* add interfaces */
835         
836         for (tc = c; tc != NULL; tc = tc->super.cls)
837                 for (i = 0; i < tc->interfacescount; i++)
838                         linker_addinterface(c, tc->interfaces[i].cls);
839         
840         RT_TIMING_GET_TIME(time_fill_iftbl);
841
842         /* add finalizer method (not for java.lang.Object) */
843
844         if (super) {
845                 methodinfo *fi;
846
847                 fi = class_findmethod(c, utf_finalize, utf_void__void);
848
849                 if (fi)
850                         if (!(fi->flags & ACC_STATIC))
851                                 c->finalizer = fi;
852         }
853         RT_TIMING_GET_TIME(time_finalizer);
854
855         /* resolve exception class references */
856
857         for (i = 0; i < c->methodscount; i++) {
858                 methodinfo *m = &(c->methods[i]);
859
860                 for (j = 0; j < m->exceptiontablelength; j++) {
861                         if (!m->exceptiontable[j].catchtype.any)
862                                 continue;
863                         if (!resolve_classref_or_classinfo(NULL,
864                                                                                            m->exceptiontable[j].catchtype,
865                                                                                            resolveEager, true, false,
866                                                                                            &(m->exceptiontable[j].catchtype.cls)))
867                                 return NULL;
868                 }
869         }
870         RT_TIMING_GET_TIME(time_exceptions);
871         
872         /* final tasks */
873
874         linker_compute_subclasses(c);
875
876         RT_TIMING_GET_TIME(time_subclasses);
877
878         /* revert the linking state and class is linked */
879
880         c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
881
882 #if !defined(NDEBUG)
883         if (linkverbose)
884                 log_message_class("Linking done class: ", c);
885 #endif
886
887         RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
888         RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
889         RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
890         RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
891         RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
892         RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
893         RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
894         RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
895         RT_TIMING_TIME_DIFF(time_finalizer    ,time_exceptions   ,RT_TIMING_LINK_EXCEPTS);
896         RT_TIMING_TIME_DIFF(time_exceptions   ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
897
898         /* just return c to show that we didn't had a problem */
899
900         return c;
901 }
902
903
904 /* link_array ******************************************************************
905
906    This function is called by link_class to create the arraydescriptor
907    for an array class.
908
909    This function returns NULL if the array cannot be linked because
910    the component type has not been linked yet.
911
912 *******************************************************************************/
913
914 static arraydescriptor *link_array(classinfo *c)
915 {
916         classinfo       *comp;
917         s4               namelen;
918         arraydescriptor *desc;
919         vftbl_t         *compvftbl;
920         utf             *u;
921
922         comp = NULL;
923         namelen = c->name->blength;
924
925         /* Check the component type */
926
927         switch (c->name->text[1]) {
928         case '[':
929                 /* c is an array of arrays. */
930                 u = utf_new(c->name->text + 1, namelen - 1);
931                 if (!(comp = load_class_from_classloader(u, c->classloader)))
932                         return NULL;
933                 break;
934
935         case 'L':
936                 /* c is an array of objects. */
937                 u = utf_new(c->name->text + 2, namelen - 3);
938                 if (!(comp = load_class_from_classloader(u, c->classloader)))
939                         return NULL;
940                 break;
941         }
942
943         /* If the component type has not been linked, link it now */
944
945         assert(!comp || (comp->state & CLASS_LOADED));
946
947         if (comp && !(comp->state & CLASS_LINKED))
948                 if (!link_class(comp))
949                         return NULL;
950
951         /* Allocate the arraydescriptor */
952
953         desc = NEW(arraydescriptor);
954
955         if (comp) {
956                 /* c is an array of references */
957                 desc->arraytype = ARRAYTYPE_OBJECT;
958                 desc->componentsize = sizeof(void*);
959                 desc->dataoffset = OFFSET(java_objectarray, data);
960                 
961                 compvftbl = comp->vftbl;
962
963                 if (!compvftbl) {
964                         log_text("Component class has no vftbl");
965                         assert(0);
966                 }
967
968                 desc->componentvftbl = compvftbl;
969                 
970                 if (compvftbl->arraydesc) {
971                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
972
973                         if (compvftbl->arraydesc->dimension >= 255) {
974                                 log_text("Creating array of dimension >255");
975                                 assert(0);
976                         }
977
978                         desc->dimension = compvftbl->arraydesc->dimension + 1;
979                         desc->elementtype = compvftbl->arraydesc->elementtype;
980
981                 } else {
982                         desc->elementvftbl = compvftbl;
983                         desc->dimension = 1;
984                         desc->elementtype = ARRAYTYPE_OBJECT;
985                 }
986
987         } else {
988                 /* c is an array of a primitive type */
989                 switch (c->name->text[1]) {
990                 case 'Z':
991                         desc->arraytype = ARRAYTYPE_BOOLEAN;
992                         desc->dataoffset = OFFSET(java_booleanarray,data);
993                         desc->componentsize = sizeof(u1);
994                         break;
995
996                 case 'B':
997                         desc->arraytype = ARRAYTYPE_BYTE;
998                         desc->dataoffset = OFFSET(java_bytearray,data);
999                         desc->componentsize = sizeof(u1);
1000                         break;
1001
1002                 case 'C':
1003                         desc->arraytype = ARRAYTYPE_CHAR;
1004                         desc->dataoffset = OFFSET(java_chararray,data);
1005                         desc->componentsize = sizeof(u2);
1006                         break;
1007
1008                 case 'D':
1009                         desc->arraytype = ARRAYTYPE_DOUBLE;
1010                         desc->dataoffset = OFFSET(java_doublearray,data);
1011                         desc->componentsize = sizeof(double);
1012                         break;
1013
1014                 case 'F':
1015                         desc->arraytype = ARRAYTYPE_FLOAT;
1016                         desc->dataoffset = OFFSET(java_floatarray,data);
1017                         desc->componentsize = sizeof(float);
1018                         break;
1019
1020                 case 'I':
1021                         desc->arraytype = ARRAYTYPE_INT;
1022                         desc->dataoffset = OFFSET(java_intarray,data);
1023                         desc->componentsize = sizeof(s4);
1024                         break;
1025
1026                 case 'J':
1027                         desc->arraytype = ARRAYTYPE_LONG;
1028                         desc->dataoffset = OFFSET(java_longarray,data);
1029                         desc->componentsize = sizeof(s8);
1030                         break;
1031
1032                 case 'S':
1033                         desc->arraytype = ARRAYTYPE_SHORT;
1034                         desc->dataoffset = OFFSET(java_shortarray,data);
1035                         desc->componentsize = sizeof(s2);
1036                         break;
1037
1038                 default:
1039                         *exceptionptr = new_noclassdeffounderror(c->name);
1040                         return NULL;
1041                 }
1042                 
1043                 desc->componentvftbl = NULL;
1044                 desc->elementvftbl = NULL;
1045                 desc->dimension = 1;
1046                 desc->elementtype = desc->arraytype;
1047         }
1048
1049         return desc;
1050 }
1051
1052
1053 /* linker_compute_subclasses ***************************************************
1054
1055    XXX
1056
1057 *******************************************************************************/
1058
1059 static void linker_compute_subclasses(classinfo *c)
1060 {
1061 #if defined(USE_THREADS)
1062 #if defined(NATIVE_THREADS)
1063         compiler_lock();
1064 #else
1065         intsDisable();
1066 #endif
1067 #endif
1068
1069         if (!(c->flags & ACC_INTERFACE)) {
1070                 c->nextsub = 0;
1071                 c->sub = 0;
1072         }
1073
1074         if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1075                 c->nextsub = c->super.cls->sub;
1076                 c->super.cls->sub = c;
1077         }
1078
1079         classvalue = 0;
1080
1081         /* compute class values */
1082
1083         linker_compute_class_values(class_java_lang_Object);
1084
1085 #if defined(USE_THREADS)
1086 #if defined(NATIVE_THREADS)
1087         compiler_unlock();
1088 #else
1089         intsRestore();
1090 #endif
1091 #endif
1092 }
1093
1094
1095 /* linker_compute_class_values *************************************************
1096
1097    XXX
1098
1099 *******************************************************************************/
1100
1101 static void linker_compute_class_values(classinfo *c)
1102 {
1103         classinfo *subs;
1104
1105         c->vftbl->baseval = ++classvalue;
1106
1107         subs = c->sub;
1108
1109         while (subs) {
1110                 linker_compute_class_values(subs);
1111
1112                 subs = subs->nextsub;
1113         }
1114
1115         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1116 }
1117
1118
1119 /* linker_addinterface *********************************************************
1120
1121    Is needed by link_class for adding a VTBL to a class. All
1122    interfaces implemented by ic are added as well.
1123
1124 *******************************************************************************/
1125
1126 static void linker_addinterface(classinfo *c, classinfo *ic)
1127 {
1128         s4     j, m;
1129         s4     i   = ic->index;
1130         vftbl_t *v = c->vftbl;
1131
1132         if (i >= v->interfacetablelength) {
1133                 log_text("Inernal error: interfacetable overflow");
1134                 assert(0);
1135         }
1136
1137         if (v->interfacetable[-i])
1138                 return;
1139
1140         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1141                 v->interfacevftbllength[i] = 1;
1142                 v->interfacetable[-i] = MNEW(methodptr, 1);
1143                 v->interfacetable[-i][0] = NULL;
1144
1145         } else {
1146                 v->interfacevftbllength[i] = ic->methodscount;
1147                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1148
1149 #if defined(ENABLE_STATISTICS)
1150                 if (opt_stat)
1151                         count_vftbl_len += sizeof(methodptr) *
1152                                 (ic->methodscount + (ic->methodscount == 0));
1153 #endif
1154
1155                 for (j = 0; j < ic->methodscount; j++) {
1156                         classinfo *sc = c;
1157
1158                         while (sc) {
1159                                 for (m = 0; m < sc->methodscount; m++) {
1160                                         methodinfo *mi = &(sc->methods[m]);
1161
1162                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1163                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1164                                                 goto foundmethod;
1165                                         }
1166                                 }
1167                                 sc = sc->super.cls;
1168                         }
1169                 foundmethod:
1170                         ;
1171                 }
1172         }
1173
1174         for (j = 0; j < ic->interfacescount; j++) 
1175                 linker_addinterface(c, ic->interfaces[j].cls);
1176 }
1177
1178
1179 /* class_highestinterface ******************************************************
1180
1181    Used by the function link_class to determine the amount of memory
1182    needed for the interface table.
1183
1184 *******************************************************************************/
1185
1186 static s4 class_highestinterface(classinfo *c)
1187 {
1188         s4 h;
1189         s4 h2;
1190         s4 i;
1191         
1192     /* check for ACC_INTERFACE bit already done in link_class_intern */
1193
1194     h = c->index;
1195
1196         for (i = 0; i < c->interfacescount; i++) {
1197                 h2 = class_highestinterface(c->interfaces[i].cls);
1198
1199                 if (h2 > h)
1200                         h = h2;
1201         }
1202
1203         return h;
1204 }
1205
1206
1207 /*
1208  * These are local overrides for various environment variables in Emacs.
1209  * Please do not remove this and leave it at the end of the file, where
1210  * Emacs will automagically detect them.
1211  * ---------------------------------------------------------------------
1212  * Local variables:
1213  * mode: c
1214  * indent-tabs-mode: t
1215  * c-basic-offset: 4
1216  * tab-width: 4
1217  * End:
1218  * vim:noexpandtab:sw=4:ts=4:
1219  */