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