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