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