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