Merged comment cleanup (forgot this before).
[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.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_length = i+1;
550                         topc->vftbl->subtype_overflow = malloc(sizeof(void*) * (i+1));
551 #if defined(ENABLE_STATISTICS)
552                         if (opt_stat)
553                                 count_vftbl_len += sizeof(void*) * (i+1);
554 #endif
555                 }
556                 topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
557                 return depth + 1;
558         }
559         topc->vftbl->subtype_display[depth] = c->vftbl;
560         return depth + 1;
561 }
562
563 static void build_display(classinfo *c)
564 {
565         int depth;
566         int i;
567
568         depth = build_display_inner(c, c, 0) - 1;
569         c->vftbl->subtype_depth = depth;
570         if (depth >= DISPLAY_SIZE)
571         {
572                 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
573         }
574         else
575         {
576                 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
577                 for (i=depth+1; i<=DISPLAY_SIZE; i++)
578                         c->vftbl->subtype_display[i] = NULL;
579                 c->vftbl->subtype_overflow_length = 0;
580         }
581 }
582
583 static classinfo *link_class_intern(classinfo *c)
584 {
585         classinfo *super;             /* super class                              */
586         classinfo *tc;                /* temporary class variable                 */
587         s4 supervftbllength;          /* vftbllegnth of super class               */
588         s4 vftbllength;               /* vftbllength of current class             */
589         s4 interfacetablelength;      /* interface table length                   */
590         vftbl_t *v;                   /* vftbl of current class                   */
591         s4 i;                         /* interface/method/field counter           */
592         arraydescriptor *arraydesc;   /* descriptor for array classes             */
593         method_worklist *worklist;    /* worklist for recompilation               */
594 #if defined(ENABLE_RT_TIMING)
595         struct timespec time_start, time_resolving, time_compute_vftbl,
596                                         time_abstract, time_compute_iftbl, time_fill_vftbl,
597                                         time_offsets, time_fill_iftbl, time_finalizer,
598                                         time_subclasses;
599 #endif
600
601         RT_TIMING_GET_TIME(time_start);
602
603         TRACELINKCLASS(c);
604
605         /* the class must be loaded */
606
607         /* XXX should this be a specific exception? */
608         assert(c->state & CLASS_LOADED);
609
610         /* This is check in link_class. */
611
612         assert(!(c->state & CLASS_LINKED));
613
614         /* cache the self-reference of this class                          */
615         /* we do this for cases where the defining loader of the class     */
616         /* has not yet been recorded as an initiating loader for the class */
617         /* this is needed so subsequent code can assume that self-refs     */
618         /* will always resolve lazily                                      */
619         /* No need to do it for the bootloader - it is always registered   */
620         /* as initiating loader for the classes it loads.                  */
621         if (c->classloader)
622                 classcache_store(c->classloader,c,false);
623
624         /* this class is currently linking */
625
626         c->state |= CLASS_LINKING;
627
628         arraydesc = NULL;
629         worklist = NULL;
630
631         /* Link the super interfaces. */
632
633         for (i = 0; i < c->interfacescount; i++) {
634                 tc = c->interfaces[i];
635
636                 if (!(tc->state & CLASS_LINKED))
637                         if (!link_class(tc))
638                                 return NULL;
639         }
640         
641         /* check super class */
642
643         super = NULL;
644
645         /* Check for java/lang/Object. */
646
647         if (c->super == NULL) {
648                 c->index = 0;
649                 c->instancesize = sizeof(java_object_t);
650                 
651                 vftbllength = supervftbllength = 0;
652
653                 c->finalizer = NULL;
654         }
655         else {
656                 /* Get super class. */
657
658                 super = c->super;
659
660                 /* Link the super class if necessary. */
661                 
662                 if (!(super->state & CLASS_LINKED))
663                         if (!link_class(super))
664                                 return NULL;
665
666                 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
667                    flags. */
668
669                 c->flags |= (super->flags &
670                                          (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
671
672                 /* handle array classes */
673
674                 if (c->name->text[0] == '[')
675                         if (!(arraydesc = link_array(c)))
676                                 return NULL;
677
678                 if (c->flags & ACC_INTERFACE)
679                         c->index = interfaceindex++;
680                 else
681                         c->index = super->index + 1;
682                 
683                 c->instancesize = super->instancesize;
684
685                 vftbllength = supervftbllength = super->vftbl->vftbllength;
686                 
687                 c->finalizer = super->finalizer;
688         }
689         RT_TIMING_GET_TIME(time_resolving);
690
691
692         /* compute vftbl length */
693
694         for (i = 0; i < c->methodscount; i++) {
695                 methodinfo *m = &(c->methods[i]);
696
697                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
698                         tc = super;
699
700                         while (tc) {
701                                 s4 j;
702
703                                 for (j = 0; j < tc->methodscount; j++) {
704                                         if (method_canoverwrite(m, &(tc->methods[j]))) {
705                                                 if (tc->methods[j].flags & ACC_PRIVATE)
706                                                         goto notfoundvftblindex;
707
708                                                 /* package-private methods in other packages */
709                                                 /* must not be overridden                    */
710                                                 /* (see Java Language Specification 8.4.8.1) */
711                                                 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
712                                                          && !SAME_PACKAGE(c,tc) ) 
713                                                 {
714                                                     goto notfoundvftblindex;
715                                                 }
716
717                                                 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
718                                                         return NULL;
719
720                                                 goto foundvftblindex;
721                                         }
722                                 }
723
724                                 tc = tc->super;
725                         }
726
727                 notfoundvftblindex:
728                         m->vftblindex = (vftbllength++);
729                 foundvftblindex:
730                         ;
731                 }
732         }
733         RT_TIMING_GET_TIME(time_compute_vftbl);
734
735
736         /* Check all interfaces of an abstract class (maybe be an
737            interface too) for unimplemented methods.  Such methods are
738            called miranda-methods and are marked with the ACC_MIRANDA
739            flag.  VMClass.getDeclaredMethods does not return such
740            methods. */
741
742         if (c->flags & ACC_ABSTRACT) {
743                 classinfo  *ic;
744                 methodinfo *im;
745                 s4 abstractmethodscount;
746                 s4 j;
747                 s4 k;
748
749                 abstractmethodscount = 0;
750
751                 /* check all interfaces of the abstract class */
752
753                 for (i = 0; i < c->interfacescount; i++) {
754                         ic = c->interfaces[i];
755
756                         for (j = 0; j < ic->methodscount; j++) {
757                                 im = &(ic->methods[j]);
758
759                                 /* skip `<clinit>' and `<init>' */
760
761                                 if ((im->name == utf_clinit) || (im->name == utf_init))
762                                         continue;
763
764                                 for (tc = c; tc != NULL; tc = tc->super) {
765                                         for (k = 0; k < tc->methodscount; k++) {
766                                                 if (method_canoverwrite(im, &(tc->methods[k])))
767                                                         goto noabstractmethod;
768                                         }
769                                 }
770
771                                 abstractmethodscount++;
772
773                         noabstractmethod:
774                                 ;
775                         }
776                 }
777
778                 if (abstractmethodscount > 0) {
779                         methodinfo *am;
780
781                         /* reallocate methods memory */
782
783                         c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
784                                                                   c->methodscount + abstractmethodscount);
785
786                         for (i = 0; i < c->interfacescount; i++) {
787                                 ic = c->interfaces[i];
788
789                                 for (j = 0; j < ic->methodscount; j++) {
790                                         im = &(ic->methods[j]);
791
792                                         /* skip `<clinit>' and `<init>' */
793
794                                         if ((im->name == utf_clinit) || (im->name == utf_init))
795                                                 continue;
796
797                                         for (tc = c; tc != NULL; tc = tc->super) {
798                                                 for (k = 0; k < tc->methodscount; k++) {
799                                                         if (method_canoverwrite(im, &(tc->methods[k])))
800                                                                 goto noabstractmethod2;
801                                                 }
802                                         }
803
804                                         /* Copy the method found into the new c->methods
805                                            array and tag it as miranda-method. */
806
807                                         am = &(c->methods[c->methodscount]);
808                                         c->methodscount++;
809
810                                         MCOPY(am, im, methodinfo, 1);
811
812                                         am->vftblindex  = (vftbllength++);
813                                         am->clazz       = c;
814                                         am->flags      |= ACC_MIRANDA;
815
816                                 noabstractmethod2:
817                                         ;
818                                 }
819                         }
820                 }
821         }
822         RT_TIMING_GET_TIME(time_abstract);
823
824
825 #if defined(ENABLE_STATISTICS)
826         if (opt_stat)
827                 count_vftbl_len +=
828                         sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
829 #endif
830
831         /* compute interfacetable length */
832
833         interfacetablelength = 0;
834
835         for (tc = c; tc != NULL; tc = tc->super) {
836                 for (i = 0; i < tc->interfacescount; i++) {
837                         s4 h = class_highestinterface(tc->interfaces[i]) + 1;
838
839                         if (h > interfacetablelength)
840                                 interfacetablelength = h;
841                 }
842         }
843         RT_TIMING_GET_TIME(time_compute_iftbl);
844
845         /* allocate virtual function table */
846
847         v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
848                                                           sizeof(methodptr) * (vftbllength - 1) +
849                                                           sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
850         v = (vftbl_t *) (((methodptr *) v) +
851                                          (interfacetablelength - 1) * (interfacetablelength > 1));
852
853         c->vftbl                = v;
854         v->clazz                = c;
855         v->vftbllength          = vftbllength;
856         v->interfacetablelength = interfacetablelength;
857         v->arraydesc            = arraydesc;
858
859         /* store interface index in vftbl */
860
861         if (c->flags & ACC_INTERFACE)
862                 v->baseval = -(c->index);
863
864         /* copy virtual function table of super class */
865
866         for (i = 0; i < supervftbllength; i++) 
867                 v->table[i] = super->vftbl->table[i];
868
869         /* Fill the remaining vftbl slots with the AbstractMethodError
870            stub (all after the super class slots, because they are already
871            initialized). */
872
873         for (; i < vftbllength; i++) {
874 #if defined(ENABLE_JIT)
875 # if defined(ENABLE_INTRP)
876                 if (opt_intrp)
877                         v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
878                 else
879 # endif
880                         v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
881 #else
882                 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
883 #endif
884         }
885
886         /* add method stubs into virtual function table */
887
888         for (i = 0; i < c->methodscount; i++) {
889                 methodinfo *m = &(c->methods[i]);
890
891                 assert(m->stubroutine == NULL);
892
893                 /* Don't create a compiler stub for abstract methods as they
894                    throw an AbstractMethodError with the default stub in the
895                    vftbl.  This entry is simply copied by sub-classes. */
896
897                 if (m->flags & ACC_ABSTRACT)
898                         continue;
899
900 #if defined(ENABLE_JIT)
901 # if defined(ENABLE_INTRP)
902                 if (opt_intrp)
903                         m->stubroutine = intrp_createcompilerstub(m);
904                 else
905 #endif
906                         m->stubroutine = CompilerStub_generate(m);
907 #else
908                 m->stubroutine = intrp_createcompilerstub(m);
909 #endif
910
911                 /* static methods are not in the vftbl */
912
913                 if (m->flags & ACC_STATIC)
914                         continue;
915
916                 /* insert the stubroutine into the vftbl */
917
918                 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
919         }
920         RT_TIMING_GET_TIME(time_fill_vftbl);
921
922         /* compute instance size and offset of each field */
923         
924         for (i = 0; i < c->fieldscount; i++) {
925                 s4 dsize;
926                 fieldinfo *f = &(c->fields[i]);
927                 
928                 if (!(f->flags & ACC_STATIC)) {
929                         dsize = descriptor_typesize(f->parseddesc);
930                         c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
931                         f->offset = c->instancesize;
932                         c->instancesize += dsize;
933                 }
934         }
935         RT_TIMING_GET_TIME(time_offsets);
936
937         /* initialize interfacetable and interfacevftbllength */
938
939         v->interfacevftbllength = MNEW(s4, interfacetablelength);
940
941 #if defined(ENABLE_STATISTICS)
942         if (opt_stat)
943                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
944 #endif
945
946         for (i = 0; i < interfacetablelength; i++) {
947                 v->interfacevftbllength[i] = 0;
948                 v->interfacetable[-i] = NULL;
949         }
950
951         /* add interfaces */
952
953         for (tc = c; tc != NULL; tc = tc->super)
954                 for (i = 0; i < tc->interfacescount; i++)
955                         if (!linker_addinterface(c, tc->interfaces[i]))
956                                 return NULL;
957
958         RT_TIMING_GET_TIME(time_fill_iftbl);
959
960         /* add finalizer method (not for java.lang.Object) */
961
962         if (super) {
963                 methodinfo *fi;
964
965                 fi = class_findmethod(c, utf_finalize, utf_void__void);
966
967                 if (fi)
968                         if (!(fi->flags & ACC_STATIC))
969                                 c->finalizer = fi;
970         }
971         RT_TIMING_GET_TIME(time_finalizer);
972
973         /* final tasks */
974
975         linker_compute_subclasses(c);
976
977         /* FIXME: this is completely useless now */
978         RT_TIMING_GET_TIME(time_subclasses);
979
980         build_display(c);
981
982         /* revert the linking state and class is linked */
983
984         c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
985
986         /* check worklist */
987
988         /* XXX must this also be done in case of exception? */
989
990         while (worklist != NULL) {
991                 method_worklist *wi = worklist;
992
993                 worklist = worklist->next;
994
995                 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
996                 jit_invalidate_code(wi->m);
997
998                 /* XXX put worklist into dump memory? */
999                 FREE(wi, method_worklist);
1000         }
1001
1002         RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
1003         RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1004         RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
1005         RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1006         RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
1007         RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
1008         RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
1009         RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
1010         RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
1011
1012         /* just return c to show that we didn't had a problem */
1013
1014         return c;
1015 }
1016
1017
1018 /* link_array ******************************************************************
1019
1020    This function is called by link_class to create the arraydescriptor
1021    for an array class.
1022
1023    This function returns NULL if the array cannot be linked because
1024    the component type has not been linked yet.
1025
1026 *******************************************************************************/
1027
1028 static arraydescriptor *link_array(classinfo *c)
1029 {
1030         classinfo       *comp;
1031         s4               namelen;
1032         arraydescriptor *desc;
1033         vftbl_t         *compvftbl;
1034         utf             *u;
1035
1036         comp = NULL;
1037         namelen = c->name->blength;
1038
1039         /* Check the component type */
1040
1041         switch (c->name->text[1]) {
1042         case '[':
1043                 /* c is an array of arrays. */
1044                 u = utf_new(c->name->text + 1, namelen - 1);
1045                 if (!(comp = load_class_from_classloader(u, c->classloader)))
1046                         return NULL;
1047                 break;
1048
1049         case 'L':
1050                 /* c is an array of objects. */
1051                 u = utf_new(c->name->text + 2, namelen - 3);
1052                 if (!(comp = load_class_from_classloader(u, c->classloader)))
1053                         return NULL;
1054                 break;
1055         }
1056
1057         /* If the component type has not been linked, link it now */
1058
1059         assert(!comp || (comp->state & CLASS_LOADED));
1060
1061         if (comp && !(comp->state & CLASS_LINKED))
1062                 if (!link_class(comp))
1063                         return NULL;
1064
1065         /* Allocate the arraydescriptor */
1066
1067         desc = NEW(arraydescriptor);
1068
1069         if (comp) {
1070                 /* c is an array of references */
1071                 desc->arraytype = ARRAYTYPE_OBJECT;
1072                 desc->componentsize = sizeof(void*);
1073                 desc->dataoffset = OFFSET(java_objectarray_t, data);
1074                 
1075                 compvftbl = comp->vftbl;
1076
1077                 if (!compvftbl) {
1078                         log_text("Component class has no vftbl");
1079                         assert(0);
1080                 }
1081
1082                 desc->componentvftbl = compvftbl;
1083                 
1084                 if (compvftbl->arraydesc) {
1085                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1086
1087                         if (compvftbl->arraydesc->dimension >= 255) {
1088                                 log_text("Creating array of dimension >255");
1089                                 assert(0);
1090                         }
1091
1092                         desc->dimension = compvftbl->arraydesc->dimension + 1;
1093                         desc->elementtype = compvftbl->arraydesc->elementtype;
1094
1095                 } else {
1096                         desc->elementvftbl = compvftbl;
1097                         desc->dimension = 1;
1098                         desc->elementtype = ARRAYTYPE_OBJECT;
1099                 }
1100
1101         } else {
1102                 /* c is an array of a primitive type */
1103                 switch (c->name->text[1]) {
1104                 case 'Z':
1105                         desc->arraytype = ARRAYTYPE_BOOLEAN;
1106                         desc->dataoffset = OFFSET(java_booleanarray_t,data);
1107                         desc->componentsize = sizeof(u1);
1108                         break;
1109
1110                 case 'B':
1111                         desc->arraytype = ARRAYTYPE_BYTE;
1112                         desc->dataoffset = OFFSET(java_bytearray_t,data);
1113                         desc->componentsize = sizeof(u1);
1114                         break;
1115
1116                 case 'C':
1117                         desc->arraytype = ARRAYTYPE_CHAR;
1118                         desc->dataoffset = OFFSET(java_chararray_t,data);
1119                         desc->componentsize = sizeof(u2);
1120                         break;
1121
1122                 case 'D':
1123                         desc->arraytype = ARRAYTYPE_DOUBLE;
1124                         desc->dataoffset = OFFSET(java_doublearray_t,data);
1125                         desc->componentsize = sizeof(double);
1126                         break;
1127
1128                 case 'F':
1129                         desc->arraytype = ARRAYTYPE_FLOAT;
1130                         desc->dataoffset = OFFSET(java_floatarray_t,data);
1131                         desc->componentsize = sizeof(float);
1132                         break;
1133
1134                 case 'I':
1135                         desc->arraytype = ARRAYTYPE_INT;
1136                         desc->dataoffset = OFFSET(java_intarray_t,data);
1137                         desc->componentsize = sizeof(s4);
1138                         break;
1139
1140                 case 'J':
1141                         desc->arraytype = ARRAYTYPE_LONG;
1142                         desc->dataoffset = OFFSET(java_longarray_t,data);
1143                         desc->componentsize = sizeof(s8);
1144                         break;
1145
1146                 case 'S':
1147                         desc->arraytype = ARRAYTYPE_SHORT;
1148                         desc->dataoffset = OFFSET(java_shortarray_t,data);
1149                         desc->componentsize = sizeof(s2);
1150                         break;
1151
1152                 default:
1153                         exceptions_throw_noclassdeffounderror(c->name);
1154                         return NULL;
1155                 }
1156                 
1157                 desc->componentvftbl = NULL;
1158                 desc->elementvftbl = NULL;
1159                 desc->dimension = 1;
1160                 desc->elementtype = desc->arraytype;
1161         }
1162
1163         return desc;
1164 }
1165
1166
1167 /* linker_compute_subclasses ***************************************************
1168
1169    XXX
1170
1171    ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1172    This function needs to take the class renumber lock and stop the
1173    world during class renumbering. The lock is used in C code which
1174    is not that performance critical. Whereas JIT code uses critical
1175    sections to atomically access the class values.
1176
1177 *******************************************************************************/
1178
1179 static void linker_compute_subclasses(classinfo *c)
1180 {
1181
1182         if (!(c->flags & ACC_INTERFACE)) {
1183                 c->nextsub = NULL;
1184                 c->sub     = NULL;
1185                 c->vftbl->baseval = 1; /* so it does not look like an interface */
1186         }
1187
1188         if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1189                 c->nextsub    = c->super->sub;
1190                 c->super->sub = c;
1191         }
1192
1193         classvalue = 0;
1194
1195 }
1196
1197
1198 /* linker_compute_class_values *************************************************
1199
1200    XXX
1201
1202 *******************************************************************************/
1203
1204 static void linker_compute_class_values(classinfo *c)
1205 {
1206         classinfo *subs;
1207
1208         c->vftbl->baseval = ++classvalue;
1209
1210         subs = c->sub;
1211
1212         while (subs) {
1213                 linker_compute_class_values(subs);
1214
1215                 subs = subs->nextsub;
1216         }
1217
1218         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1219 }
1220
1221
1222 /* linker_addinterface *********************************************************
1223
1224    Is needed by link_class for adding a VTBL to a class. All
1225    interfaces implemented by ic are added as well.
1226
1227    RETURN VALUE:
1228       true.........everything ok
1229           false........an exception has been thrown
1230
1231 *******************************************************************************/
1232
1233 static bool linker_addinterface(classinfo *c, classinfo *ic)
1234 {
1235         s4          j, k;
1236         vftbl_t    *v;
1237         s4          i;
1238         classinfo  *sc;
1239         methodinfo *m;
1240
1241         v = c->vftbl;
1242         i = ic->index;
1243
1244         if (i >= v->interfacetablelength)
1245                 vm_abort("Internal error: interfacetable overflow");
1246
1247         /* if this interface has already been added, return immediately */
1248
1249         if (v->interfacetable[-i] != NULL)
1250                 return true;
1251
1252         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1253                 v->interfacevftbllength[i] = 1;
1254                 v->interfacetable[-i]      = MNEW(methodptr, 1);
1255                 v->interfacetable[-i][0]   = NULL;
1256         }
1257         else {
1258                 v->interfacevftbllength[i] = ic->methodscount;
1259                 v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
1260
1261 #if defined(ENABLE_STATISTICS)
1262                 if (opt_stat)
1263                         count_vftbl_len += sizeof(methodptr) *
1264                                 (ic->methodscount + (ic->methodscount == 0));
1265 #endif
1266
1267                 for (j = 0; j < ic->methodscount; j++) {
1268                         for (sc = c; sc != NULL; sc = sc->super) {
1269                                 for (k = 0; k < sc->methodscount; k++) {
1270                                         m = &(sc->methods[k]);
1271
1272                                         if (method_canoverwrite(m, &(ic->methods[j]))) {
1273                                                 /* method m overwrites the (abstract) method */
1274 #if defined(ENABLE_VERIFIER)
1275                                                 /* Add loading constraints (for the more
1276                                                    general types of the method
1277                                                    ic->methods[j]).  */
1278                                                 if (!classcache_add_constraints_for_params(
1279                                                                         c->classloader, ic->classloader,
1280                                                                         &(ic->methods[j])))
1281                                                 {
1282                                                         return false;
1283                                                 }
1284 #endif
1285
1286                                                 /* XXX taken from gcj */
1287                                                 /* check for ACC_STATIC: IncompatibleClassChangeError */
1288
1289                                                 /* check for !ACC_PUBLIC: IllegalAccessError */
1290
1291                                                 /* check for ACC_ABSTRACT: AbstracMethodError,
1292                                                    not sure about that one */
1293
1294                                                 v->interfacetable[-i][j] = v->table[m->vftblindex];
1295                                                 goto foundmethod;
1296                                         }
1297                                 }
1298                         }
1299
1300                         /* If no method was found, insert the AbstractMethodError
1301                            stub. */
1302
1303 #if defined(ENABLE_JIT)
1304 # if defined(ENABLE_INTRP)
1305                         if (opt_intrp)
1306                                 v->interfacetable[-i][j] =
1307                                         (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1308                         else
1309 # endif
1310                                 v->interfacetable[-i][j] =
1311                                         (methodptr) (ptrint) &asm_abstractmethoderror;
1312 #else
1313                         v->interfacetable[-i][j] =
1314                                 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1315 #endif
1316
1317                 foundmethod:
1318                         ;
1319                 }
1320         }
1321
1322         /* add superinterfaces of this interface */
1323
1324         for (j = 0; j < ic->interfacescount; j++)
1325                 if (!linker_addinterface(c, ic->interfaces[j]))
1326                         return false;
1327
1328         /* everything ok */
1329
1330         return true;
1331 }
1332
1333
1334 /* class_highestinterface ******************************************************
1335
1336    Used by the function link_class to determine the amount of memory
1337    needed for the interface table.
1338
1339 *******************************************************************************/
1340
1341 static s4 class_highestinterface(classinfo *c)
1342 {
1343         s4 h;
1344         s4 h2;
1345         s4 i;
1346         
1347     /* check for ACC_INTERFACE bit already done in link_class_intern */
1348
1349     h = c->index;
1350
1351         for (i = 0; i < c->interfacescount; i++) {
1352                 h2 = class_highestinterface(c->interfaces[i]);
1353
1354                 if (h2 > h)
1355                         h = h2;
1356         }
1357
1358         return h;
1359 }
1360
1361
1362 /*
1363  * These are local overrides for various environment variables in Emacs.
1364  * Please do not remove this and leave it at the end of the file, where
1365  * Emacs will automagically detect them.
1366  * ---------------------------------------------------------------------
1367  * Local variables:
1368  * mode: c
1369  * indent-tabs-mode: t
1370  * c-basic-offset: 4
1371  * tab-width: 4
1372  * End:
1373  * vim:noexpandtab:sw=4:ts=4:
1374  */