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