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");
283 /* some classes which may be used more often */
285 #if defined(ENABLE_JAVASE)
286 if (!link_class(class_java_lang_StackTraceElement))
287 vm_abort("linker_init: linking failed");
289 if (!link_class(class_java_lang_reflect_Constructor))
290 vm_abort("linker_init: linking failed");
292 if (!link_class(class_java_lang_reflect_Field))
293 vm_abort("linker_init: linking failed");
295 if (!link_class(class_java_lang_reflect_Method))
296 vm_abort("linker_init: linking failed");
298 if (!link_class(class_java_security_PrivilegedAction))
299 vm_abort("linker_init: linking failed");
301 if (!link_class(class_java_util_Vector))
302 vm_abort("linker_init: linking failed");
304 if (!link_class(class_java_util_HashMap))
305 vm_abort("linker_init: linking failed");
307 # if defined(WITH_CLASSPATH_SUN)
308 if (!link_class(class_sun_reflect_MagicAccessorImpl))
309 vm_abort("linker_init: linking failed");
312 if (!link_class(arrayclass_java_lang_Object))
313 vm_abort("linker_init: linking failed");
317 /* create pseudo classes used by the typechecker */
319 /* pseudo class for Arraystubs (extends java.lang.Object) */
321 pseudo_class_Arraystub =
322 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
323 pseudo_class_Arraystub->state |= CLASS_LOADED;
324 pseudo_class_Arraystub->super = class_java_lang_Object;
326 #if defined(ENABLE_JAVASE)
328 pseudo_class_Arraystub->interfacescount = 2;
329 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
330 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
331 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
333 #elif defined(ENABLE_JAVAME_CLDC1_1)
335 pseudo_class_Arraystub->interfacescount = 0;
336 pseudo_class_Arraystub->interfaces = NULL;
339 # error unknown Java configuration
342 if (!classcache_store_unique(pseudo_class_Arraystub))
343 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
345 if (!link_class(pseudo_class_Arraystub))
346 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
348 /* pseudo class representing the null type */
350 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
351 pseudo_class_Null->state |= CLASS_LOADED;
352 pseudo_class_Null->super = class_java_lang_Object;
354 if (!classcache_store_unique(pseudo_class_Null))
355 vm_abort("linker_init: could not cache pseudo_class_Null");
357 if (!link_class(pseudo_class_Null))
358 vm_abort("linker_init: linking failed");
360 /* pseudo class representing new uninitialized objects */
362 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
363 pseudo_class_New->state |= CLASS_LOADED;
364 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
365 pseudo_class_New->super = class_java_lang_Object;
367 if (!classcache_store_unique(pseudo_class_New))
368 vm_abort("linker_init: could not cache pseudo_class_New");
370 /* Correct vftbl-entries (retarded loading and linking of class
371 java/lang/String). */
373 stringtable_update();
377 /* link_class ******************************************************************
379 Wrapper function for link_class_intern to ease monitor enter/exit
380 and exception handling.
382 *******************************************************************************/
384 classinfo *link_class(classinfo *c)
387 #if defined(ENABLE_RT_TIMING)
388 struct timespec time_start, time_end;
391 RT_TIMING_GET_TIME(time_start);
394 exceptions_throw_nullpointerexception();
398 LOCK_MONITOR_ENTER(c);
400 /* Maybe the class is currently linking or is already linked.*/
402 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
403 LOCK_MONITOR_EXIT(c);
408 #if defined(ENABLE_STATISTICS)
411 if (opt_getcompilingtime)
412 compilingtime_stop();
414 if (opt_getloadingtime)
418 /* call the internal function */
420 r = link_class_intern(c);
422 /* If return value is NULL, we had a problem and the class is not
426 c->state &= ~CLASS_LINKING;
428 #if defined(ENABLE_STATISTICS)
431 if (opt_getloadingtime)
434 if (opt_getcompilingtime)
435 compilingtime_start();
438 LOCK_MONITOR_EXIT(c);
440 RT_TIMING_GET_TIME(time_end);
442 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
448 /* linker_overwrite_method *****************************************************
450 Overwrite a method with another one, update method flags and check
454 mg................the general method being overwritten
455 ms................the overwriting (more specialized) method
456 wl................worklist where to add invalidated methods
459 true..............everything ok
460 false.............an exception has been thrown
462 *******************************************************************************/
464 static bool linker_overwrite_method(methodinfo *mg,
466 method_worklist **wl)
474 /* overriding a final method is illegal */
476 if (mg->flags & ACC_FINAL) {
477 exceptions_throw_verifyerror(mg, "Overriding final method");
481 /* method ms overwrites method mg */
483 #if defined(ENABLE_VERIFIER)
484 /* Add loading constraints (for the more general types of method mg). */
485 /* Not for <init>, as it is not invoked virtually. */
487 if ((ms->name != utf_init)
488 && !classcache_add_constraints_for_params(
489 cs->classloader, cg->classloader, mg))
495 /* inherit the vftbl index, and record the overwriting */
497 ms->vftblindex = mg->vftblindex;
500 /* update flags and check assumptions */
501 /* <init> methods are a special case, as they are never dispatched dynamically */
503 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
505 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
506 /* this adds another implementation */
508 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
510 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
512 method_break_assumption_monomorphic(mg, wl);
515 /* this is the first implementation */
517 mg->flags |= ACC_METHOD_IMPLEMENTED;
519 INLINELOG( printf("becomes implemented: "); method_println(mg); );
524 } while (mg != NULL);
531 /* link_class_intern ***********************************************************
533 Tries to link a class. The function calculates the length in bytes
534 that an instance of this class requires as well as the VTBL for
535 methods and interface methods.
537 *******************************************************************************/
539 static classinfo *link_class_intern(classinfo *c)
541 classinfo *super; /* super class */
542 classinfo *tc; /* temporary class variable */
543 s4 supervftbllength; /* vftbllegnth of super class */
544 s4 vftbllength; /* vftbllength of current class */
545 s4 interfacetablelength; /* interface table length */
546 vftbl_t *v; /* vftbl of current class */
547 s4 i; /* interface/method/field counter */
548 arraydescriptor *arraydesc; /* descriptor for array classes */
549 method_worklist *worklist; /* worklist for recompilation */
550 #if defined(ENABLE_RT_TIMING)
551 struct timespec time_start, time_resolving, time_compute_vftbl,
552 time_abstract, time_compute_iftbl, time_fill_vftbl,
553 time_offsets, time_fill_iftbl, time_finalizer,
557 RT_TIMING_GET_TIME(time_start);
561 /* the class must be loaded */
563 /* XXX should this be a specific exception? */
564 assert(c->state & CLASS_LOADED);
566 /* This is check in link_class. */
568 assert(!(c->state & CLASS_LINKED));
570 /* cache the self-reference of this class */
571 /* we do this for cases where the defining loader of the class */
572 /* has not yet been recorded as an initiating loader for the class */
573 /* this is needed so subsequent code can assume that self-refs */
574 /* will always resolve lazily */
575 /* No need to do it for the bootloader - it is always registered */
576 /* as initiating loader for the classes it loads. */
578 classcache_store(c->classloader,c,false);
580 /* this class is currently linking */
582 c->state |= CLASS_LINKING;
587 /* Link the super interfaces. */
589 for (i = 0; i < c->interfacescount; i++) {
590 tc = c->interfaces[i];
592 if (!(tc->state & CLASS_LINKED))
597 /* check super class */
601 /* Check for java/lang/Object. */
603 if (c->super == NULL) {
605 c->instancesize = sizeof(java_object_t);
607 vftbllength = supervftbllength = 0;
612 /* Get super class. */
616 /* Link the super class if necessary. */
618 if (!(super->state & CLASS_LINKED))
619 if (!link_class(super))
622 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
625 c->flags |= (super->flags &
626 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
628 /* handle array classes */
630 if (c->name->text[0] == '[')
631 if (!(arraydesc = link_array(c)))
634 if (c->flags & ACC_INTERFACE)
635 c->index = interfaceindex++;
637 c->index = super->index + 1;
639 c->instancesize = super->instancesize;
641 vftbllength = supervftbllength = super->vftbl->vftbllength;
643 c->finalizer = super->finalizer;
645 RT_TIMING_GET_TIME(time_resolving);
648 /* compute vftbl length */
650 for (i = 0; i < c->methodscount; i++) {
651 methodinfo *m = &(c->methods[i]);
653 if (!(m->flags & ACC_STATIC)) { /* is instance method */
659 for (j = 0; j < tc->methodscount; j++) {
660 if (method_canoverwrite(m, &(tc->methods[j]))) {
661 if (tc->methods[j].flags & ACC_PRIVATE)
662 goto notfoundvftblindex;
664 /* package-private methods in other packages */
665 /* must not be overridden */
666 /* (see Java Language Specification 8.4.8.1) */
667 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
668 && !SAME_PACKAGE(c,tc) )
670 goto notfoundvftblindex;
673 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
676 goto foundvftblindex;
684 m->vftblindex = (vftbllength++);
689 RT_TIMING_GET_TIME(time_compute_vftbl);
692 /* Check all interfaces of an abstract class (maybe be an
693 interface too) for unimplemented methods. Such methods are
694 called miranda-methods and are marked with the ACC_MIRANDA
695 flag. VMClass.getDeclaredMethods does not return such
698 if (c->flags & ACC_ABSTRACT) {
701 s4 abstractmethodscount;
705 abstractmethodscount = 0;
707 /* check all interfaces of the abstract class */
709 for (i = 0; i < c->interfacescount; i++) {
710 ic = c->interfaces[i];
712 for (j = 0; j < ic->methodscount; j++) {
713 im = &(ic->methods[j]);
715 /* skip `<clinit>' and `<init>' */
717 if ((im->name == utf_clinit) || (im->name == utf_init))
720 for (tc = c; tc != NULL; tc = tc->super) {
721 for (k = 0; k < tc->methodscount; k++) {
722 if (method_canoverwrite(im, &(tc->methods[k])))
723 goto noabstractmethod;
727 abstractmethodscount++;
734 if (abstractmethodscount > 0) {
737 /* reallocate methods memory */
739 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
740 c->methodscount + abstractmethodscount);
742 for (i = 0; i < c->interfacescount; i++) {
743 ic = c->interfaces[i];
745 for (j = 0; j < ic->methodscount; j++) {
746 im = &(ic->methods[j]);
748 /* skip `<clinit>' and `<init>' */
750 if ((im->name == utf_clinit) || (im->name == utf_init))
753 for (tc = c; tc != NULL; tc = tc->super) {
754 for (k = 0; k < tc->methodscount; k++) {
755 if (method_canoverwrite(im, &(tc->methods[k])))
756 goto noabstractmethod2;
760 /* Copy the method found into the new c->methods
761 array and tag it as miranda-method. */
763 am = &(c->methods[c->methodscount]);
766 MCOPY(am, im, methodinfo, 1);
768 am->vftblindex = (vftbllength++);
770 am->flags |= ACC_MIRANDA;
778 RT_TIMING_GET_TIME(time_abstract);
781 #if defined(ENABLE_STATISTICS)
784 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
787 /* compute interfacetable length */
789 interfacetablelength = 0;
791 for (tc = c; tc != NULL; tc = tc->super) {
792 for (i = 0; i < tc->interfacescount; i++) {
793 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
795 if (h > interfacetablelength)
796 interfacetablelength = h;
799 RT_TIMING_GET_TIME(time_compute_iftbl);
801 /* allocate virtual function table */
803 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
804 sizeof(methodptr) * (vftbllength - 1) +
805 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
806 v = (vftbl_t *) (((methodptr *) v) +
807 (interfacetablelength - 1) * (interfacetablelength > 1));
811 v->vftbllength = vftbllength;
812 v->interfacetablelength = interfacetablelength;
813 v->arraydesc = arraydesc;
815 /* store interface index in vftbl */
817 if (c->flags & ACC_INTERFACE)
818 v->baseval = -(c->index);
820 /* copy virtual function table of super class */
822 for (i = 0; i < supervftbllength; i++)
823 v->table[i] = super->vftbl->table[i];
825 /* Fill the remaining vftbl slots with the AbstractMethodError
826 stub (all after the super class slots, because they are already
829 for (; i < vftbllength; i++) {
830 #if defined(ENABLE_JIT)
831 # if defined(ENABLE_INTRP)
833 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
836 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
838 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
842 /* add method stubs into virtual function table */
844 for (i = 0; i < c->methodscount; i++) {
845 methodinfo *m = &(c->methods[i]);
847 assert(m->stubroutine == NULL);
849 /* Don't create a compiler stub for abstract methods as they
850 throw an AbstractMethodError with the default stub in the
851 vftbl. This entry is simply copied by sub-classes. */
853 if (m->flags & ACC_ABSTRACT)
856 #if defined(ENABLE_JIT)
857 # if defined(ENABLE_INTRP)
859 m->stubroutine = intrp_createcompilerstub(m);
862 m->stubroutine = codegen_generate_stub_compiler(m);
864 m->stubroutine = intrp_createcompilerstub(m);
867 /* static methods are not in the vftbl */
869 if (m->flags & ACC_STATIC)
872 /* insert the stubroutine into the vftbl */
874 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
876 RT_TIMING_GET_TIME(time_fill_vftbl);
878 /* compute instance size and offset of each field */
880 for (i = 0; i < c->fieldscount; i++) {
882 fieldinfo *f = &(c->fields[i]);
884 if (!(f->flags & ACC_STATIC)) {
885 dsize = descriptor_typesize(f->parseddesc);
887 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
888 /* On some architectures and configurations we need to
889 align long (int64_t) and double fields to 4-bytes to
890 match what GCC does for struct members. We must do the
891 same as GCC here because the offsets in native header
892 structs like java_lang_Double must match the offsets of
893 the Java fields (eg. java.lang.Double.value). */
895 # if LINKER_ALIGNMENT_LONG_DOUBLE != 4
896 # error alignment of long and double is not 4
899 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
902 # if LINKER_ALIGNMENT_LONG_DOUBLE != 8
903 # error alignment of long and double is not 8
906 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
909 f->offset = c->instancesize;
910 c->instancesize += dsize;
913 RT_TIMING_GET_TIME(time_offsets);
915 /* initialize interfacetable and interfacevftbllength */
917 v->interfacevftbllength = MNEW(s4, interfacetablelength);
919 #if defined(ENABLE_STATISTICS)
921 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
924 for (i = 0; i < interfacetablelength; i++) {
925 v->interfacevftbllength[i] = 0;
926 v->interfacetable[-i] = NULL;
931 for (tc = c; tc != NULL; tc = tc->super)
932 for (i = 0; i < tc->interfacescount; i++)
933 if (!linker_addinterface(c, tc->interfaces[i]))
936 RT_TIMING_GET_TIME(time_fill_iftbl);
938 /* add finalizer method (not for java.lang.Object) */
943 fi = class_findmethod(c, utf_finalize, utf_void__void);
946 if (!(fi->flags & ACC_STATIC))
949 RT_TIMING_GET_TIME(time_finalizer);
953 linker_compute_subclasses(c);
955 RT_TIMING_GET_TIME(time_subclasses);
957 /* revert the linking state and class is linked */
959 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
963 /* XXX must this also be done in case of exception? */
965 while (worklist != NULL) {
966 method_worklist *wi = worklist;
968 worklist = worklist->next;
970 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
971 jit_invalidate_code(wi->m);
973 /* XXX put worklist into dump memory? */
974 FREE(wi, method_worklist);
977 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
978 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
979 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
980 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
981 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
982 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
983 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
984 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
985 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
987 /* just return c to show that we didn't had a problem */
993 /* link_array ******************************************************************
995 This function is called by link_class to create the arraydescriptor
998 This function returns NULL if the array cannot be linked because
999 the component type has not been linked yet.
1001 *******************************************************************************/
1003 static arraydescriptor *link_array(classinfo *c)
1007 arraydescriptor *desc;
1012 namelen = c->name->blength;
1014 /* Check the component type */
1016 switch (c->name->text[1]) {
1018 /* c is an array of arrays. */
1019 u = utf_new(c->name->text + 1, namelen - 1);
1020 if (!(comp = load_class_from_classloader(u, c->classloader)))
1025 /* c is an array of objects. */
1026 u = utf_new(c->name->text + 2, namelen - 3);
1027 if (!(comp = load_class_from_classloader(u, c->classloader)))
1032 /* If the component type has not been linked, link it now */
1034 assert(!comp || (comp->state & CLASS_LOADED));
1036 if (comp && !(comp->state & CLASS_LINKED))
1037 if (!link_class(comp))
1040 /* Allocate the arraydescriptor */
1042 desc = NEW(arraydescriptor);
1045 /* c is an array of references */
1046 desc->arraytype = ARRAYTYPE_OBJECT;
1047 desc->componentsize = sizeof(void*);
1048 desc->dataoffset = OFFSET(java_objectarray_t, data);
1050 compvftbl = comp->vftbl;
1053 log_text("Component class has no vftbl");
1057 desc->componentvftbl = compvftbl;
1059 if (compvftbl->arraydesc) {
1060 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1062 if (compvftbl->arraydesc->dimension >= 255) {
1063 log_text("Creating array of dimension >255");
1067 desc->dimension = compvftbl->arraydesc->dimension + 1;
1068 desc->elementtype = compvftbl->arraydesc->elementtype;
1071 desc->elementvftbl = compvftbl;
1072 desc->dimension = 1;
1073 desc->elementtype = ARRAYTYPE_OBJECT;
1077 /* c is an array of a primitive type */
1078 switch (c->name->text[1]) {
1080 desc->arraytype = ARRAYTYPE_BOOLEAN;
1081 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1082 desc->componentsize = sizeof(u1);
1086 desc->arraytype = ARRAYTYPE_BYTE;
1087 desc->dataoffset = OFFSET(java_bytearray_t,data);
1088 desc->componentsize = sizeof(u1);
1092 desc->arraytype = ARRAYTYPE_CHAR;
1093 desc->dataoffset = OFFSET(java_chararray_t,data);
1094 desc->componentsize = sizeof(u2);
1098 desc->arraytype = ARRAYTYPE_DOUBLE;
1099 desc->dataoffset = OFFSET(java_doublearray_t,data);
1100 desc->componentsize = sizeof(double);
1104 desc->arraytype = ARRAYTYPE_FLOAT;
1105 desc->dataoffset = OFFSET(java_floatarray_t,data);
1106 desc->componentsize = sizeof(float);
1110 desc->arraytype = ARRAYTYPE_INT;
1111 desc->dataoffset = OFFSET(java_intarray_t,data);
1112 desc->componentsize = sizeof(s4);
1116 desc->arraytype = ARRAYTYPE_LONG;
1117 desc->dataoffset = OFFSET(java_longarray_t,data);
1118 desc->componentsize = sizeof(s8);
1122 desc->arraytype = ARRAYTYPE_SHORT;
1123 desc->dataoffset = OFFSET(java_shortarray_t,data);
1124 desc->componentsize = sizeof(s2);
1128 exceptions_throw_noclassdeffounderror(c->name);
1132 desc->componentvftbl = NULL;
1133 desc->elementvftbl = NULL;
1134 desc->dimension = 1;
1135 desc->elementtype = desc->arraytype;
1142 /* linker_compute_subclasses ***************************************************
1146 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1147 This function needs to take the class renumber lock and stop the
1148 world during class renumbering. The lock is used in C code which
1149 is not that performance critical. Whereas JIT code uses critical
1150 sections to atomically access the class values.
1152 *******************************************************************************/
1154 static void linker_compute_subclasses(classinfo *c)
1156 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1158 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1159 threads_stopworld();
1162 if (!(c->flags & ACC_INTERFACE)) {
1167 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1168 c->nextsub = c->super->sub;
1174 /* compute class values */
1176 linker_compute_class_values(class_java_lang_Object);
1178 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1180 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1181 threads_startworld();
1186 /* linker_compute_class_values *************************************************
1190 *******************************************************************************/
1192 static void linker_compute_class_values(classinfo *c)
1196 c->vftbl->baseval = ++classvalue;
1201 linker_compute_class_values(subs);
1203 subs = subs->nextsub;
1206 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1210 /* linker_addinterface *********************************************************
1212 Is needed by link_class for adding a VTBL to a class. All
1213 interfaces implemented by ic are added as well.
1216 true.........everything ok
1217 false........an exception has been thrown
1219 *******************************************************************************/
1221 static bool linker_addinterface(classinfo *c, classinfo *ic)
1232 if (i >= v->interfacetablelength)
1233 vm_abort("Internal error: interfacetable overflow");
1235 /* if this interface has already been added, return immediately */
1237 if (v->interfacetable[-i] != NULL)
1240 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1241 v->interfacevftbllength[i] = 1;
1242 v->interfacetable[-i] = MNEW(methodptr, 1);
1243 v->interfacetable[-i][0] = NULL;
1246 v->interfacevftbllength[i] = ic->methodscount;
1247 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1249 #if defined(ENABLE_STATISTICS)
1251 count_vftbl_len += sizeof(methodptr) *
1252 (ic->methodscount + (ic->methodscount == 0));
1255 for (j = 0; j < ic->methodscount; j++) {
1256 for (sc = c; sc != NULL; sc = sc->super) {
1257 for (k = 0; k < sc->methodscount; k++) {
1258 m = &(sc->methods[k]);
1260 if (method_canoverwrite(m, &(ic->methods[j]))) {
1261 /* method m overwrites the (abstract) method */
1262 #if defined(ENABLE_VERIFIER)
1263 /* Add loading constraints (for the more
1264 general types of the method
1266 if (!classcache_add_constraints_for_params(
1267 c->classloader, ic->classloader,
1274 /* XXX taken from gcj */
1275 /* check for ACC_STATIC: IncompatibleClassChangeError */
1277 /* check for !ACC_PUBLIC: IllegalAccessError */
1279 /* check for ACC_ABSTRACT: AbstracMethodError,
1280 not sure about that one */
1282 v->interfacetable[-i][j] = v->table[m->vftblindex];
1288 /* If no method was found, insert the AbstractMethodError
1291 #if defined(ENABLE_JIT)
1292 # if defined(ENABLE_INTRP)
1294 v->interfacetable[-i][j] =
1295 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1298 v->interfacetable[-i][j] =
1299 (methodptr) (ptrint) &asm_abstractmethoderror;
1301 v->interfacetable[-i][j] =
1302 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1310 /* add superinterfaces of this interface */
1312 for (j = 0; j < ic->interfacescount; j++)
1313 if (!linker_addinterface(c, ic->interfaces[j]))
1322 /* class_highestinterface ******************************************************
1324 Used by the function link_class to determine the amount of memory
1325 needed for the interface table.
1327 *******************************************************************************/
1329 static s4 class_highestinterface(classinfo *c)
1335 /* check for ACC_INTERFACE bit already done in link_class_intern */
1339 for (i = 0; i < c->interfacescount; i++) {
1340 h2 = class_highestinterface(c->interfaces[i]);
1351 * These are local overrides for various environment variables in Emacs.
1352 * Please do not remove this and leave it at the end of the file, where
1353 * Emacs will automagically detect them.
1354 * ---------------------------------------------------------------------
1357 * indent-tabs-mode: t
1361 * vim:noexpandtab:sw=4:ts=4: