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