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