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