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