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