1 /* src/vmcore/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
33 #include "mm/memory.h"
35 #include "native/native.h"
37 #include "threads/lock-common.h"
39 #include "toolbox/logging.h"
41 #include "vm/access.h"
43 #include "vm/exceptions.h"
44 #include "vm/primitive.h"
45 #include "vm/stringlocal.h"
48 #include "vm/jit_interface.h"
50 #include "vmcore/class.h"
51 #include "vmcore/classcache.h"
52 #include "vmcore/loader.h"
53 #include "vmcore/options.h"
54 #include "vmcore/rt-timing.h"
57 /* debugging macros ***********************************************************/
60 # define TRACELINKCLASS(c) \
62 if (opt_TraceLinkClass) { \
64 log_print("[Linking "); \
71 # define TRACELINKCLASS(c)
75 /* #include "vm/resolve.h" */
76 /* copied prototype to avoid bootstrapping problem: */
77 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
79 #if defined(ENABLE_STATISTICS)
80 # include "vmcore/statistics.h"
83 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
84 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
86 #define INLINELOG(code)
90 /* global variables ***********************************************************/
92 static s4 interfaceindex; /* sequential numbering of interfaces */
95 java_object_t *linker_classrenumber_lock;
98 /* private functions **********************************************************/
100 static classinfo *link_class_intern(classinfo *c);
101 static arraydescriptor *link_array(classinfo *c);
102 static void linker_compute_class_values(classinfo *c);
103 static void linker_compute_subclasses(classinfo *c);
104 static bool linker_addinterface(classinfo *c, classinfo *ic);
105 static s4 class_highestinterface(classinfo *c);
108 /* dummy structures for alinment checks ***************************************/
110 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
111 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
113 struct dummy_alignment_long_t {
118 struct dummy_alignment_double_t {
124 /* linker_init *****************************************************************
126 Initializes the linker subsystem and links classes required for the
129 *******************************************************************************/
131 void linker_preinit(void)
133 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
135 /* Check for if alignment for long and double matches what we
136 assume for the current architecture. */
138 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
139 /* Define a define here which is later checked when we use this
142 # define LINKER_ALIGNMENT_LONG_DOUBLE 4
144 if (OFFSET(dummy_alignment_long_t, l) != 4)
145 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
146 OFFSET(dummy_alignment_long_t, l), 4);
148 if (OFFSET(dummy_alignment_double_t, d) != 4)
149 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
150 OFFSET(dummy_alignment_double_t, d), 4);
153 # define LINKER_ALIGNMENT_LONG_DOUBLE 8
155 if (OFFSET(dummy_alignment_long_t, l) != 8)
156 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
157 OFFSET(dummy_alignment_long_t, l), 8);
159 if (OFFSET(dummy_alignment_double_t, d) != 8)
160 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
161 OFFSET(dummy_alignment_double_t, d), 8);
164 /* Reset interface index. */
168 #if defined(ENABLE_THREADS)
169 /* create the global lock object */
171 linker_classrenumber_lock = NEW(java_object_t);
173 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
176 /* Link the most basic classes. */
178 if (!link_class(class_java_lang_Object))
179 vm_abort("linker_preinit: linking java/lang/Object failed");
181 #if defined(ENABLE_JAVASE)
182 if (!link_class(class_java_lang_Cloneable))
183 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
185 if (!link_class(class_java_io_Serializable))
186 vm_abort("linker_preinit: linking java/io/Serializable failed");
191 /* linker_init *****************************************************************
193 Links all classes required in the VM.
195 *******************************************************************************/
197 void linker_init(void)
199 TRACESUBSYSTEMINITIALIZATION("linker_init");
201 /* Link java.lang.Class as first class of the system, because we
202 need it's vftbl for all other classes so we can use a class as
205 if (!link_class(class_java_lang_Class))
206 vm_abort("linker_init: linking java/lang/Class failed");
208 /* Now set the header.vftbl of all classes which were created
209 before java.lang.Class was linked. */
211 class_postset_header_vftbl();
213 /* Link primitive-type wrapping classes. */
215 #if defined(ENABLE_JAVASE)
216 if (!link_class(class_java_lang_Void))
217 vm_abort("linker_init: linking failed");
220 if (!link_class(class_java_lang_Boolean))
221 vm_abort("linker_init: linking failed");
223 if (!link_class(class_java_lang_Byte))
224 vm_abort("linker_init: linking failed");
226 if (!link_class(class_java_lang_Character))
227 vm_abort("linker_init: linking failed");
229 if (!link_class(class_java_lang_Short))
230 vm_abort("linker_init: linking failed");
232 if (!link_class(class_java_lang_Integer))
233 vm_abort("linker_init: linking failed");
235 if (!link_class(class_java_lang_Long))
236 vm_abort("linker_init: linking failed");
238 if (!link_class(class_java_lang_Float))
239 vm_abort("linker_init: linking failed");
241 if (!link_class(class_java_lang_Double))
242 vm_abort("linker_init: linking failed");
244 /* Link important system classes. */
246 if (!link_class(class_java_lang_String))
247 vm_abort("linker_init: linking java/lang/String failed");
249 #if defined(ENABLE_JAVASE)
250 if (!link_class(class_java_lang_ClassLoader))
251 vm_abort("linker_init: linking failed");
253 if (!link_class(class_java_lang_SecurityManager))
254 vm_abort("linker_init: linking failed");
257 if (!link_class(class_java_lang_System))
258 vm_abort("linker_init: linking failed");
260 if (!link_class(class_java_lang_Thread))
261 vm_abort("linker_init: linking failed");
263 #if defined(ENABLE_JAVASE)
264 if (!link_class(class_java_lang_ThreadGroup))
265 vm_abort("linker_init: linking failed");
268 if (!link_class(class_java_lang_Throwable))
269 vm_abort("linker_init: linking failed");
271 #if defined(WITH_CLASSPATH_GNU)
272 if (!link_class(class_java_lang_VMSystem))
273 vm_abort("linker_init: linking failed");
275 if (!link_class(class_java_lang_VMThread))
276 vm_abort("linker_init: linking failed");
278 if (!link_class(class_java_lang_VMThrowable))
279 vm_abort("linker_init: linking failed");
282 /* Important system exceptions. */
284 if (!link_class(class_java_lang_Exception))
285 vm_abort("linker_init: linking failed");
287 if (!link_class(class_java_lang_ClassNotFoundException))
288 vm_abort("linker_init: linking failed");
290 if (!link_class(class_java_lang_RuntimeException))
291 vm_abort("linker_init: linking failed");
293 /* some classes which may be used more often */
295 #if defined(ENABLE_JAVASE)
296 if (!link_class(class_java_lang_StackTraceElement))
297 vm_abort("linker_init: linking failed");
299 if (!link_class(class_java_lang_reflect_Constructor))
300 vm_abort("linker_init: linking failed");
302 if (!link_class(class_java_lang_reflect_Field))
303 vm_abort("linker_init: linking failed");
305 if (!link_class(class_java_lang_reflect_Method))
306 vm_abort("linker_init: linking failed");
308 if (!link_class(class_java_security_PrivilegedAction))
309 vm_abort("linker_init: linking failed");
311 if (!link_class(class_java_util_Vector))
312 vm_abort("linker_init: linking failed");
314 if (!link_class(class_java_util_HashMap))
315 vm_abort("linker_init: linking failed");
317 # if defined(WITH_CLASSPATH_SUN)
318 if (!link_class(class_sun_reflect_MagicAccessorImpl))
319 vm_abort("linker_init: linking failed");
322 if (!link_class(arrayclass_java_lang_Object))
323 vm_abort("linker_init: linking failed");
327 /* create pseudo classes used by the typechecker */
329 /* pseudo class for Arraystubs (extends java.lang.Object) */
331 pseudo_class_Arraystub =
332 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
333 pseudo_class_Arraystub->state |= CLASS_LOADED;
334 pseudo_class_Arraystub->super = class_java_lang_Object;
336 #if defined(ENABLE_JAVASE)
338 pseudo_class_Arraystub->interfacescount = 2;
339 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
340 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
341 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
343 #elif defined(ENABLE_JAVAME_CLDC1_1)
345 pseudo_class_Arraystub->interfacescount = 0;
346 pseudo_class_Arraystub->interfaces = NULL;
349 # error unknown Java configuration
352 if (!classcache_store_unique(pseudo_class_Arraystub))
353 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
355 if (!link_class(pseudo_class_Arraystub))
356 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
358 /* pseudo class representing the null type */
360 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
361 pseudo_class_Null->state |= CLASS_LOADED;
362 pseudo_class_Null->super = class_java_lang_Object;
364 if (!classcache_store_unique(pseudo_class_Null))
365 vm_abort("linker_init: could not cache pseudo_class_Null");
367 if (!link_class(pseudo_class_Null))
368 vm_abort("linker_init: linking failed");
370 /* pseudo class representing new uninitialized objects */
372 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
373 pseudo_class_New->state |= CLASS_LOADED;
374 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
375 pseudo_class_New->super = class_java_lang_Object;
377 if (!classcache_store_unique(pseudo_class_New))
378 vm_abort("linker_init: could not cache pseudo_class_New");
380 /* Correct vftbl-entries (retarded loading and linking of class
381 java/lang/String). */
383 stringtable_update();
387 /* link_class ******************************************************************
389 Wrapper function for link_class_intern to ease monitor enter/exit
390 and exception handling.
392 *******************************************************************************/
394 classinfo *link_class(classinfo *c)
397 #if defined(ENABLE_RT_TIMING)
398 struct timespec time_start, time_end;
401 RT_TIMING_GET_TIME(time_start);
404 exceptions_throw_nullpointerexception();
408 LOCK_MONITOR_ENTER(c);
410 /* Maybe the class is currently linking or is already linked.*/
412 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
413 LOCK_MONITOR_EXIT(c);
418 #if defined(ENABLE_STATISTICS)
421 if (opt_getcompilingtime)
422 compilingtime_stop();
424 if (opt_getloadingtime)
428 /* call the internal function */
430 r = link_class_intern(c);
432 /* If return value is NULL, we had a problem and the class is not
436 c->state &= ~CLASS_LINKING;
438 #if defined(ENABLE_STATISTICS)
441 if (opt_getloadingtime)
444 if (opt_getcompilingtime)
445 compilingtime_start();
448 LOCK_MONITOR_EXIT(c);
450 RT_TIMING_GET_TIME(time_end);
452 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
458 /* linker_overwrite_method *****************************************************
460 Overwrite a method with another one, update method flags and check
464 mg................the general method being overwritten
465 ms................the overwriting (more specialized) method
466 wl................worklist where to add invalidated methods
469 true..............everything ok
470 false.............an exception has been thrown
472 *******************************************************************************/
474 static bool linker_overwrite_method(methodinfo *mg,
476 method_worklist **wl)
484 /* overriding a final method is illegal */
486 if (mg->flags & ACC_FINAL) {
487 exceptions_throw_verifyerror(mg, "Overriding final method");
491 /* method ms overwrites method mg */
493 #if defined(ENABLE_VERIFIER)
494 /* Add loading constraints (for the more general types of method mg). */
495 /* Not for <init>, as it is not invoked virtually. */
497 if ((ms->name != utf_init)
498 && !classcache_add_constraints_for_params(
499 cs->classloader, cg->classloader, mg))
505 /* inherit the vftbl index, and record the overwriting */
507 ms->vftblindex = mg->vftblindex;
510 /* update flags and check assumptions */
511 /* <init> methods are a special case, as they are never dispatched dynamically */
513 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
515 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
516 /* this adds another implementation */
518 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
520 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
522 method_break_assumption_monomorphic(mg, wl);
525 /* this is the first implementation */
527 mg->flags |= ACC_METHOD_IMPLEMENTED;
529 INLINELOG( printf("becomes implemented: "); method_println(mg); );
534 } while (mg != NULL);
541 /* link_class_intern ***********************************************************
543 Tries to link a class. The function calculates the length in bytes
544 that an instance of this class requires as well as the VTBL for
545 methods and interface methods.
547 *******************************************************************************/
549 static classinfo *link_class_intern(classinfo *c)
551 classinfo *super; /* super class */
552 classinfo *tc; /* temporary class variable */
553 s4 supervftbllength; /* vftbllegnth of super class */
554 s4 vftbllength; /* vftbllength of current class */
555 s4 interfacetablelength; /* interface table length */
556 vftbl_t *v; /* vftbl of current class */
557 s4 i; /* interface/method/field counter */
558 arraydescriptor *arraydesc; /* descriptor for array classes */
559 method_worklist *worklist; /* worklist for recompilation */
560 #if defined(ENABLE_RT_TIMING)
561 struct timespec time_start, time_resolving, time_compute_vftbl,
562 time_abstract, time_compute_iftbl, time_fill_vftbl,
563 time_offsets, time_fill_iftbl, time_finalizer,
567 RT_TIMING_GET_TIME(time_start);
571 /* the class must be loaded */
573 /* XXX should this be a specific exception? */
574 assert(c->state & CLASS_LOADED);
576 /* This is check in link_class. */
578 assert(!(c->state & CLASS_LINKED));
580 /* cache the self-reference of this class */
581 /* we do this for cases where the defining loader of the class */
582 /* has not yet been recorded as an initiating loader for the class */
583 /* this is needed so subsequent code can assume that self-refs */
584 /* will always resolve lazily */
585 /* No need to do it for the bootloader - it is always registered */
586 /* as initiating loader for the classes it loads. */
588 classcache_store(c->classloader,c,false);
590 /* this class is currently linking */
592 c->state |= CLASS_LINKING;
597 /* Link the super interfaces. */
599 for (i = 0; i < c->interfacescount; i++) {
600 tc = c->interfaces[i];
602 if (!(tc->state & CLASS_LINKED))
607 /* check super class */
611 /* Check for java/lang/Object. */
613 if (c->super == NULL) {
615 c->instancesize = sizeof(java_object_t);
617 vftbllength = supervftbllength = 0;
622 /* Get super class. */
626 /* Link the super class if necessary. */
628 if (!(super->state & CLASS_LINKED))
629 if (!link_class(super))
632 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
635 c->flags |= (super->flags &
636 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
638 /* handle array classes */
640 if (c->name->text[0] == '[')
641 if (!(arraydesc = link_array(c)))
644 if (c->flags & ACC_INTERFACE)
645 c->index = interfaceindex++;
647 c->index = super->index + 1;
649 c->instancesize = super->instancesize;
651 vftbllength = supervftbllength = super->vftbl->vftbllength;
653 c->finalizer = super->finalizer;
655 RT_TIMING_GET_TIME(time_resolving);
658 /* compute vftbl length */
660 for (i = 0; i < c->methodscount; i++) {
661 methodinfo *m = &(c->methods[i]);
663 if (!(m->flags & ACC_STATIC)) { /* is instance method */
669 for (j = 0; j < tc->methodscount; j++) {
670 if (method_canoverwrite(m, &(tc->methods[j]))) {
671 if (tc->methods[j].flags & ACC_PRIVATE)
672 goto notfoundvftblindex;
674 /* package-private methods in other packages */
675 /* must not be overridden */
676 /* (see Java Language Specification 8.4.8.1) */
677 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
678 && !SAME_PACKAGE(c,tc) )
680 goto notfoundvftblindex;
683 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
686 goto foundvftblindex;
694 m->vftblindex = (vftbllength++);
699 RT_TIMING_GET_TIME(time_compute_vftbl);
702 /* Check all interfaces of an abstract class (maybe be an
703 interface too) for unimplemented methods. Such methods are
704 called miranda-methods and are marked with the ACC_MIRANDA
705 flag. VMClass.getDeclaredMethods does not return such
708 if (c->flags & ACC_ABSTRACT) {
711 s4 abstractmethodscount;
715 abstractmethodscount = 0;
717 /* check all interfaces of the abstract class */
719 for (i = 0; i < c->interfacescount; i++) {
720 ic = c->interfaces[i];
722 for (j = 0; j < ic->methodscount; j++) {
723 im = &(ic->methods[j]);
725 /* skip `<clinit>' and `<init>' */
727 if ((im->name == utf_clinit) || (im->name == utf_init))
730 for (tc = c; tc != NULL; tc = tc->super) {
731 for (k = 0; k < tc->methodscount; k++) {
732 if (method_canoverwrite(im, &(tc->methods[k])))
733 goto noabstractmethod;
737 abstractmethodscount++;
744 if (abstractmethodscount > 0) {
747 /* reallocate methods memory */
749 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
750 c->methodscount + abstractmethodscount);
752 for (i = 0; i < c->interfacescount; i++) {
753 ic = c->interfaces[i];
755 for (j = 0; j < ic->methodscount; j++) {
756 im = &(ic->methods[j]);
758 /* skip `<clinit>' and `<init>' */
760 if ((im->name == utf_clinit) || (im->name == utf_init))
763 for (tc = c; tc != NULL; tc = tc->super) {
764 for (k = 0; k < tc->methodscount; k++) {
765 if (method_canoverwrite(im, &(tc->methods[k])))
766 goto noabstractmethod2;
770 /* Copy the method found into the new c->methods
771 array and tag it as miranda-method. */
773 am = &(c->methods[c->methodscount]);
776 MCOPY(am, im, methodinfo, 1);
778 am->vftblindex = (vftbllength++);
780 am->flags |= ACC_MIRANDA;
788 RT_TIMING_GET_TIME(time_abstract);
791 #if defined(ENABLE_STATISTICS)
794 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
797 /* compute interfacetable length */
799 interfacetablelength = 0;
801 for (tc = c; tc != NULL; tc = tc->super) {
802 for (i = 0; i < tc->interfacescount; i++) {
803 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
805 if (h > interfacetablelength)
806 interfacetablelength = h;
809 RT_TIMING_GET_TIME(time_compute_iftbl);
811 /* allocate virtual function table */
813 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
814 sizeof(methodptr) * (vftbllength - 1) +
815 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
816 v = (vftbl_t *) (((methodptr *) v) +
817 (interfacetablelength - 1) * (interfacetablelength > 1));
821 v->vftbllength = vftbllength;
822 v->interfacetablelength = interfacetablelength;
823 v->arraydesc = arraydesc;
825 /* store interface index in vftbl */
827 if (c->flags & ACC_INTERFACE)
828 v->baseval = -(c->index);
830 /* copy virtual function table of super class */
832 for (i = 0; i < supervftbllength; i++)
833 v->table[i] = super->vftbl->table[i];
835 /* Fill the remaining vftbl slots with the AbstractMethodError
836 stub (all after the super class slots, because they are already
839 for (; i < vftbllength; i++) {
840 #if defined(ENABLE_JIT)
841 # if defined(ENABLE_INTRP)
843 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
846 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
848 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
852 /* add method stubs into virtual function table */
854 for (i = 0; i < c->methodscount; i++) {
855 methodinfo *m = &(c->methods[i]);
857 assert(m->stubroutine == NULL);
859 /* Don't create a compiler stub for abstract methods as they
860 throw an AbstractMethodError with the default stub in the
861 vftbl. This entry is simply copied by sub-classes. */
863 if (m->flags & ACC_ABSTRACT)
866 #if defined(ENABLE_JIT)
867 # if defined(ENABLE_INTRP)
869 m->stubroutine = intrp_createcompilerstub(m);
872 m->stubroutine = codegen_generate_stub_compiler(m);
874 m->stubroutine = intrp_createcompilerstub(m);
877 /* static methods are not in the vftbl */
879 if (m->flags & ACC_STATIC)
882 /* insert the stubroutine into the vftbl */
884 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
886 RT_TIMING_GET_TIME(time_fill_vftbl);
888 /* compute instance size and offset of each field */
890 for (i = 0; i < c->fieldscount; i++) {
892 fieldinfo *f = &(c->fields[i]);
894 if (!(f->flags & ACC_STATIC)) {
895 dsize = descriptor_typesize(f->parseddesc);
897 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
898 /* On some architectures and configurations we need to
899 align long (int64_t) and double fields to 4-bytes to
900 match what GCC does for struct members. We must do the
901 same as GCC here because the offsets in native header
902 structs like java_lang_Double must match the offsets of
903 the Java fields (eg. java.lang.Double.value). */
905 # if LINKER_ALIGNMENT_LONG_DOUBLE != 4
906 # error alignment of long and double is not 4
909 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
912 # if LINKER_ALIGNMENT_LONG_DOUBLE != 8
913 # error alignment of long and double is not 8
916 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
919 f->offset = c->instancesize;
920 c->instancesize += dsize;
923 RT_TIMING_GET_TIME(time_offsets);
925 /* initialize interfacetable and interfacevftbllength */
927 v->interfacevftbllength = MNEW(s4, interfacetablelength);
929 #if defined(ENABLE_STATISTICS)
931 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
934 for (i = 0; i < interfacetablelength; i++) {
935 v->interfacevftbllength[i] = 0;
936 v->interfacetable[-i] = NULL;
941 for (tc = c; tc != NULL; tc = tc->super)
942 for (i = 0; i < tc->interfacescount; i++)
943 if (!linker_addinterface(c, tc->interfaces[i]))
946 RT_TIMING_GET_TIME(time_fill_iftbl);
948 /* add finalizer method (not for java.lang.Object) */
953 fi = class_findmethod(c, utf_finalize, utf_void__void);
956 if (!(fi->flags & ACC_STATIC))
959 RT_TIMING_GET_TIME(time_finalizer);
963 linker_compute_subclasses(c);
965 RT_TIMING_GET_TIME(time_subclasses);
967 /* revert the linking state and class is linked */
969 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
973 /* XXX must this also be done in case of exception? */
975 while (worklist != NULL) {
976 method_worklist *wi = worklist;
978 worklist = worklist->next;
980 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
981 jit_invalidate_code(wi->m);
983 /* XXX put worklist into dump memory? */
984 FREE(wi, method_worklist);
987 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
988 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
989 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
990 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
991 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
992 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
993 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
994 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
995 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
997 /* just return c to show that we didn't had a problem */
1003 /* link_array ******************************************************************
1005 This function is called by link_class to create the arraydescriptor
1008 This function returns NULL if the array cannot be linked because
1009 the component type has not been linked yet.
1011 *******************************************************************************/
1013 static arraydescriptor *link_array(classinfo *c)
1017 arraydescriptor *desc;
1022 namelen = c->name->blength;
1024 /* Check the component type */
1026 switch (c->name->text[1]) {
1028 /* c is an array of arrays. */
1029 u = utf_new(c->name->text + 1, namelen - 1);
1030 if (!(comp = load_class_from_classloader(u, c->classloader)))
1035 /* c is an array of objects. */
1036 u = utf_new(c->name->text + 2, namelen - 3);
1037 if (!(comp = load_class_from_classloader(u, c->classloader)))
1042 /* If the component type has not been linked, link it now */
1044 assert(!comp || (comp->state & CLASS_LOADED));
1046 if (comp && !(comp->state & CLASS_LINKED))
1047 if (!link_class(comp))
1050 /* Allocate the arraydescriptor */
1052 desc = NEW(arraydescriptor);
1055 /* c is an array of references */
1056 desc->arraytype = ARRAYTYPE_OBJECT;
1057 desc->componentsize = sizeof(void*);
1058 desc->dataoffset = OFFSET(java_objectarray_t, data);
1060 compvftbl = comp->vftbl;
1063 log_text("Component class has no vftbl");
1067 desc->componentvftbl = compvftbl;
1069 if (compvftbl->arraydesc) {
1070 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1072 if (compvftbl->arraydesc->dimension >= 255) {
1073 log_text("Creating array of dimension >255");
1077 desc->dimension = compvftbl->arraydesc->dimension + 1;
1078 desc->elementtype = compvftbl->arraydesc->elementtype;
1081 desc->elementvftbl = compvftbl;
1082 desc->dimension = 1;
1083 desc->elementtype = ARRAYTYPE_OBJECT;
1087 /* c is an array of a primitive type */
1088 switch (c->name->text[1]) {
1090 desc->arraytype = ARRAYTYPE_BOOLEAN;
1091 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1092 desc->componentsize = sizeof(u1);
1096 desc->arraytype = ARRAYTYPE_BYTE;
1097 desc->dataoffset = OFFSET(java_bytearray_t,data);
1098 desc->componentsize = sizeof(u1);
1102 desc->arraytype = ARRAYTYPE_CHAR;
1103 desc->dataoffset = OFFSET(java_chararray_t,data);
1104 desc->componentsize = sizeof(u2);
1108 desc->arraytype = ARRAYTYPE_DOUBLE;
1109 desc->dataoffset = OFFSET(java_doublearray_t,data);
1110 desc->componentsize = sizeof(double);
1114 desc->arraytype = ARRAYTYPE_FLOAT;
1115 desc->dataoffset = OFFSET(java_floatarray_t,data);
1116 desc->componentsize = sizeof(float);
1120 desc->arraytype = ARRAYTYPE_INT;
1121 desc->dataoffset = OFFSET(java_intarray_t,data);
1122 desc->componentsize = sizeof(s4);
1126 desc->arraytype = ARRAYTYPE_LONG;
1127 desc->dataoffset = OFFSET(java_longarray_t,data);
1128 desc->componentsize = sizeof(s8);
1132 desc->arraytype = ARRAYTYPE_SHORT;
1133 desc->dataoffset = OFFSET(java_shortarray_t,data);
1134 desc->componentsize = sizeof(s2);
1138 exceptions_throw_noclassdeffounderror(c->name);
1142 desc->componentvftbl = NULL;
1143 desc->elementvftbl = NULL;
1144 desc->dimension = 1;
1145 desc->elementtype = desc->arraytype;
1152 /* linker_compute_subclasses ***************************************************
1156 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1157 This function needs to take the class renumber lock and stop the
1158 world during class renumbering. The lock is used in C code which
1159 is not that performance critical. Whereas JIT code uses critical
1160 sections to atomically access the class values.
1162 *******************************************************************************/
1164 static void linker_compute_subclasses(classinfo *c)
1166 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1168 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1169 threads_stopworld();
1172 if (!(c->flags & ACC_INTERFACE)) {
1177 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1178 c->nextsub = c->super->sub;
1184 /* compute class values */
1186 linker_compute_class_values(class_java_lang_Object);
1188 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1190 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1191 threads_startworld();
1196 /* linker_compute_class_values *************************************************
1200 *******************************************************************************/
1202 static void linker_compute_class_values(classinfo *c)
1206 c->vftbl->baseval = ++classvalue;
1211 linker_compute_class_values(subs);
1213 subs = subs->nextsub;
1216 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1220 /* linker_addinterface *********************************************************
1222 Is needed by link_class for adding a VTBL to a class. All
1223 interfaces implemented by ic are added as well.
1226 true.........everything ok
1227 false........an exception has been thrown
1229 *******************************************************************************/
1231 static bool linker_addinterface(classinfo *c, classinfo *ic)
1242 if (i >= v->interfacetablelength)
1243 vm_abort("Internal error: interfacetable overflow");
1245 /* if this interface has already been added, return immediately */
1247 if (v->interfacetable[-i] != NULL)
1250 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1251 v->interfacevftbllength[i] = 1;
1252 v->interfacetable[-i] = MNEW(methodptr, 1);
1253 v->interfacetable[-i][0] = NULL;
1256 v->interfacevftbllength[i] = ic->methodscount;
1257 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1259 #if defined(ENABLE_STATISTICS)
1261 count_vftbl_len += sizeof(methodptr) *
1262 (ic->methodscount + (ic->methodscount == 0));
1265 for (j = 0; j < ic->methodscount; j++) {
1266 for (sc = c; sc != NULL; sc = sc->super) {
1267 for (k = 0; k < sc->methodscount; k++) {
1268 m = &(sc->methods[k]);
1270 if (method_canoverwrite(m, &(ic->methods[j]))) {
1271 /* method m overwrites the (abstract) method */
1272 #if defined(ENABLE_VERIFIER)
1273 /* Add loading constraints (for the more
1274 general types of the method
1276 if (!classcache_add_constraints_for_params(
1277 c->classloader, ic->classloader,
1284 /* XXX taken from gcj */
1285 /* check for ACC_STATIC: IncompatibleClassChangeError */
1287 /* check for !ACC_PUBLIC: IllegalAccessError */
1289 /* check for ACC_ABSTRACT: AbstracMethodError,
1290 not sure about that one */
1292 v->interfacetable[-i][j] = v->table[m->vftblindex];
1298 /* If no method was found, insert the AbstractMethodError
1301 #if defined(ENABLE_JIT)
1302 # if defined(ENABLE_INTRP)
1304 v->interfacetable[-i][j] =
1305 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1308 v->interfacetable[-i][j] =
1309 (methodptr) (ptrint) &asm_abstractmethoderror;
1311 v->interfacetable[-i][j] =
1312 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1320 /* add superinterfaces of this interface */
1322 for (j = 0; j < ic->interfacescount; j++)
1323 if (!linker_addinterface(c, ic->interfaces[j]))
1332 /* class_highestinterface ******************************************************
1334 Used by the function link_class to determine the amount of memory
1335 needed for the interface table.
1337 *******************************************************************************/
1339 static s4 class_highestinterface(classinfo *c)
1345 /* check for ACC_INTERFACE bit already done in link_class_intern */
1349 for (i = 0; i < c->interfacescount; i++) {
1350 h2 = class_highestinterface(c->interfaces[i]);
1361 * These are local overrides for various environment variables in Emacs.
1362 * Please do not remove this and leave it at the end of the file, where
1363 * Emacs will automagically detect them.
1364 * ---------------------------------------------------------------------
1367 * indent-tabs-mode: t
1371 * vim:noexpandtab:sw=4:ts=4: