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