1 /* src/vm/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: linker.c 5975 2006-11-12 15:33:16Z edwin $
46 #include "mm/memory.h"
47 #include "native/native.h"
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/lock.h"
52 # include "threads/none/lock.h"
56 #include "vm/classcache.h"
57 #include "vm/exceptions.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/resolve.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
63 #include "vm/access.h"
64 #include "vm/rt-timing.h"
66 #include "vm/jit/asmpart.h"
69 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
70 extern bool inline_debug_log;
71 #define INLINELOG(code) do { if (inline_debug_log) { code } } while (0)
73 #define INLINELOG(code)
77 /* global variables ***********************************************************/
79 static s4 interfaceindex; /* sequential numbering of interfaces */
83 /* primitivetype_table *********************************************************
85 Structure for primitive classes: contains the class for wrapping
86 the primitive type, the primitive class, the name of the class for
87 wrapping, the one character type signature and the name of the
90 CAUTION: Don't change the order of the types. This table is indexed
91 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
93 *******************************************************************************/
95 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
96 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
97 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
98 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
99 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
100 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
101 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
102 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
103 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
104 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
105 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
106 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
110 /* private functions **********************************************************/
112 static bool link_primitivetype_table(void);
113 static classinfo *link_class_intern(classinfo *c);
114 static arraydescriptor *link_array(classinfo *c);
115 static void linker_compute_class_values(classinfo *c);
116 static void linker_compute_subclasses(classinfo *c);
117 static bool linker_addinterface(classinfo *c, classinfo *ic);
118 static s4 class_highestinterface(classinfo *c);
121 /* linker_init *****************************************************************
123 Initializes the linker subsystem.
125 *******************************************************************************/
127 bool linker_init(void)
129 /* reset interface index */
133 /* link java.lang.Class as first class of the system, because we
134 need it's vftbl for all other classes so we can use a class as
137 if (!link_class(class_java_lang_Class))
140 /* now set the header.vftbl of all classes which were created
141 before java.lang.Class was linked */
143 class_postset_header_vftbl();
146 /* link important system classes */
148 if (!link_class(class_java_lang_Object))
151 if (!link_class(class_java_lang_String))
154 if (!link_class(class_java_lang_Cloneable))
157 if (!link_class(class_java_io_Serializable))
161 /* link classes for wrapping primitive types */
163 if (!link_class(class_java_lang_Void))
166 if (!link_class(class_java_lang_Boolean))
169 if (!link_class(class_java_lang_Byte))
172 if (!link_class(class_java_lang_Character))
175 if (!link_class(class_java_lang_Short))
178 if (!link_class(class_java_lang_Integer))
181 if (!link_class(class_java_lang_Long))
184 if (!link_class(class_java_lang_Float))
187 if (!link_class(class_java_lang_Double))
191 /* load some other important classes */
193 if (!link_class(class_java_lang_ClassLoader))
196 if (!link_class(class_java_lang_SecurityManager))
199 if (!link_class(class_java_lang_System))
202 if (!link_class(class_java_lang_Thread))
205 if (!link_class(class_java_lang_ThreadGroup))
208 if (!link_class(class_java_lang_VMSystem))
211 if (!link_class(class_java_lang_VMThread))
215 /* some classes which may be used more often */
217 if (!link_class(class_java_lang_StackTraceElement))
220 if (!link_class(class_java_lang_reflect_Constructor))
223 if (!link_class(class_java_lang_reflect_Field))
226 if (!link_class(class_java_lang_reflect_Method))
229 if (!link_class(class_java_security_PrivilegedAction))
232 if (!link_class(class_java_util_Vector))
235 if (!link_class(arrayclass_java_lang_Object))
239 /* create pseudo classes used by the typechecker */
241 /* pseudo class for Arraystubs (extends java.lang.Object) */
243 pseudo_class_Arraystub =
244 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
245 pseudo_class_Arraystub->state |= CLASS_LOADED;
246 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
247 pseudo_class_Arraystub->interfacescount = 2;
248 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
249 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
250 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
252 if (!classcache_store_unique(pseudo_class_Arraystub)) {
253 log_text("could not cache pseudo_class_Arraystub");
257 if (!link_class(pseudo_class_Arraystub))
260 /* pseudo class representing the null type */
262 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
263 pseudo_class_Null->state |= CLASS_LOADED;
264 pseudo_class_Null->super.cls = class_java_lang_Object;
266 if (!classcache_store_unique(pseudo_class_Null)) {
267 log_text("could not cache pseudo_class_Null");
271 if (!link_class(pseudo_class_Null))
274 /* pseudo class representing new uninitialized objects */
276 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
277 pseudo_class_New->state |= CLASS_LOADED;
278 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
279 pseudo_class_New->super.cls = class_java_lang_Object;
281 if (!classcache_store_unique(pseudo_class_New)) {
282 log_text("could not cache pseudo_class_New");
286 /* create classes representing primitive types */
288 if (!link_primitivetype_table())
292 /* Correct vftbl-entries (retarded loading and linking of class */
293 /* java/lang/String). */
295 stringtable_update();
301 /* link_primitivetype_table ****************************************************
303 Create classes representing primitive types.
305 *******************************************************************************/
307 static bool link_primitivetype_table(void)
313 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
316 if (!primitivetype_table[i].name)
319 /* create primitive class */
321 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
323 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
325 /* prevent loader from loading primitive class */
327 c->state |= CLASS_LOADED;
329 /* INFO: don't put primitive classes into the classcache */
334 primitivetype_table[i].class_primitive = c;
336 /* create class for wrapping the primitive type */
338 u = utf_new_char(primitivetype_table[i].wrapname);
340 if (!(c = load_class_bootstrap(u)))
343 primitivetype_table[i].class_wrap = c;
345 /* create the primitive array class */
347 if (primitivetype_table[i].arrayname) {
348 u = utf_new_char(primitivetype_table[i].arrayname);
349 c = class_create_classinfo(u);
350 c = load_newly_created_array(c, NULL);
354 primitivetype_table[i].arrayclass = c;
356 assert(c->state & CLASS_LOADED);
358 if (!(c->state & CLASS_LINKED))
362 primitivetype_table[i].arrayvftbl = c->vftbl;
370 /* link_class ******************************************************************
372 Wrapper function for link_class_intern to ease monitor enter/exit
373 and exception handling.
375 *******************************************************************************/
377 classinfo *link_class(classinfo *c)
380 #if defined(ENABLE_RT_TIMING)
381 struct timespec time_start, time_end;
384 RT_TIMING_GET_TIME(time_start);
387 exceptions_throw_nullpointerexception();
391 LOCK_MONITOR_ENTER(c);
393 /* maybe the class is already linked */
395 if (c->state & CLASS_LINKED) {
396 LOCK_MONITOR_EXIT(c);
401 #if defined(ENABLE_STATISTICS)
404 if (opt_getcompilingtime)
405 compilingtime_stop();
407 if (opt_getloadingtime)
411 /* call the internal function */
413 r = link_class_intern(c);
415 /* if return value is NULL, we had a problem and the class is not linked */
418 c->state &= ~CLASS_LINKING;
420 #if defined(ENABLE_STATISTICS)
423 if (opt_getloadingtime)
426 if (opt_getcompilingtime)
427 compilingtime_start();
430 LOCK_MONITOR_EXIT(c);
432 RT_TIMING_GET_TIME(time_end);
434 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
440 /* linker_overwrite_method *****************************************************
442 Overwrite a method with another one, update method flags and check
446 mg................the general method being overwritten
447 ms................the overwriting (more specialized) method
448 wl................worklist where to add invalidated methods
451 true..............everything ok
452 false.............an exception has been thrown
454 *******************************************************************************/
456 static bool linker_overwrite_method(methodinfo *mg,
458 method_worklist **wl)
466 /* overriding a final method is illegal */
468 if (mg->flags & ACC_FINAL) {
470 new_exception(string_java_lang_VerifyError);
474 /* method ms overwrites method mg */
476 #if defined(ENABLE_VERIFIER)
477 /* Add loading constraints (for the more general types of method mg). */
478 /* Not for <init>, as it is not invoked virtually. */
480 if ((ms->name != utf_init)
481 && !classcache_add_constraints_for_params(
482 cs->classloader, cg->classloader, mg))
488 /* inherit the vftbl index, and record the overwriting */
490 ms->vftblindex = mg->vftblindex;
493 /* update flags and check assumptions */
494 /* <init> methods are a special case, as they are never dispatched dynamically */
496 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
498 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
499 /* this adds another implementation */
501 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
503 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
505 method_break_assumption_monomorphic(mg, wl);
508 /* this is the first implementation */
510 mg->flags |= ACC_METHOD_IMPLEMENTED;
512 INLINELOG( printf("becomes implemented: "); method_println(mg); );
517 } while (mg != NULL);
524 /* link_class_intern ***********************************************************
526 Tries to link a class. The function calculates the length in bytes
527 that an instance of this class requires as well as the VTBL for
528 methods and interface methods.
530 *******************************************************************************/
532 static classinfo *link_class_intern(classinfo *c)
534 classinfo *super; /* super class */
535 classinfo *tc; /* temporary class variable */
536 s4 supervftbllength; /* vftbllegnth of super class */
537 s4 vftbllength; /* vftbllength of current class */
538 s4 interfacetablelength; /* interface table length */
539 vftbl_t *v; /* vftbl of current class */
540 s4 i; /* interface/method/field counter */
541 arraydescriptor *arraydesc; /* descriptor for array classes */
542 method_worklist *worklist; /* worklist for recompilation */
543 #if defined(ENABLE_RT_TIMING)
544 struct timespec time_start, time_resolving, time_compute_vftbl,
545 time_abstract, time_compute_iftbl, time_fill_vftbl,
546 time_offsets, time_fill_iftbl, time_finalizer,
550 RT_TIMING_GET_TIME(time_start);
552 /* the class is already linked */
554 if (c->state & CLASS_LINKED)
559 log_message_class("Linking class: ", c);
562 /* the class must be loaded */
564 /* XXX should this be a specific exception? */
565 assert(c->state & CLASS_LOADED);
567 /* cache the self-reference of this class */
568 /* we do this for cases where the defining loader of the class */
569 /* has not yet been recorded as an initiating loader for the class */
570 /* this is needed so subsequent code can assume that self-refs */
571 /* will always resolve lazily */
572 /* No need to do it for the bootloader - it is always registered */
573 /* as initiating loader for the classes it loads. */
575 classcache_store(c->classloader,c,false);
577 /* this class is currently linking */
579 c->state |= CLASS_LINKING;
584 /* check interfaces */
586 for (i = 0; i < c->interfacescount; i++) {
587 /* resolve this super interface */
589 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
593 c->interfaces[i].cls = tc;
595 /* detect circularity */
599 new_exception_utfmessage(string_java_lang_ClassCircularityError,
604 assert(tc->state & CLASS_LOADED);
606 if (!(tc->flags & ACC_INTERFACE)) {
608 new_exception_message(string_java_lang_IncompatibleClassChangeError,
609 "Implementing class");
613 if (!(tc->state & CLASS_LINKED))
618 /* check super class */
622 if (c->super.any == NULL) { /* class java.lang.Object */
624 c->instancesize = sizeof(java_objectheader);
626 vftbllength = supervftbllength = 0;
631 /* resolve super class */
633 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
636 c->super.cls = super;
638 /* detect circularity */
642 new_exception_utfmessage(string_java_lang_ClassCircularityError,
647 assert(super->state & CLASS_LOADED);
649 if (super->flags & ACC_INTERFACE) {
650 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
651 log_text("Interface specified as super class");
655 /* Don't allow extending final classes */
657 if (super->flags & ACC_FINAL) {
659 new_exception_message(string_java_lang_VerifyError,
660 "Cannot inherit from final class");
664 /* link the superclass if necessary */
666 if (!(super->state & CLASS_LINKED))
667 if (!link_class(super))
670 /* OR the ACC_CLASS_HAS_POINTERS flag */
672 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
674 /* handle array classes */
676 if (c->name->text[0] == '[')
677 if (!(arraydesc = link_array(c)))
680 if (c->flags & ACC_INTERFACE)
681 c->index = interfaceindex++;
683 c->index = super->index + 1;
685 c->instancesize = super->instancesize;
687 vftbllength = supervftbllength = super->vftbl->vftbllength;
689 c->finalizer = super->finalizer;
691 RT_TIMING_GET_TIME(time_resolving);
694 /* compute vftbl length */
696 for (i = 0; i < c->methodscount; i++) {
697 methodinfo *m = &(c->methods[i]);
699 if (!(m->flags & ACC_STATIC)) { /* is instance method */
705 for (j = 0; j < tc->methodscount; j++) {
706 if (method_canoverwrite(m, &(tc->methods[j]))) {
707 if (tc->methods[j].flags & ACC_PRIVATE)
708 goto notfoundvftblindex;
710 /* package-private methods in other packages */
711 /* must not be overridden */
712 /* (see Java Language Specification 8.4.8.1) */
713 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
714 && !SAME_PACKAGE(c,tc) )
716 goto notfoundvftblindex;
719 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
722 goto foundvftblindex;
730 m->vftblindex = (vftbllength++);
735 RT_TIMING_GET_TIME(time_compute_vftbl);
738 /* Check all interfaces of an abstract class (maybe be an
739 interface too) for unimplemented methods. Such methods are
740 called miranda-methods and are marked with the ACC_MIRANDA
741 flag. VMClass.getDeclaredMethods does not return such
744 if (c->flags & ACC_ABSTRACT) {
747 s4 abstractmethodscount;
751 abstractmethodscount = 0;
753 /* check all interfaces of the abstract class */
755 for (i = 0; i < c->interfacescount; i++) {
756 ic = c->interfaces[i].cls;
758 for (j = 0; j < ic->methodscount; j++) {
759 im = &(ic->methods[j]);
761 /* skip `<clinit>' and `<init>' */
763 if ((im->name == utf_clinit) || (im->name == utf_init))
766 for (tc = c; tc != NULL; tc = tc->super.cls) {
767 for (k = 0; k < tc->methodscount; k++) {
768 if (method_canoverwrite(im, &(tc->methods[k])))
769 goto noabstractmethod;
773 abstractmethodscount++;
780 if (abstractmethodscount > 0) {
783 /* reallocate methods memory */
785 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
786 c->methodscount + abstractmethodscount);
788 for (i = 0; i < c->interfacescount; i++) {
789 ic = c->interfaces[i].cls;
791 for (j = 0; j < ic->methodscount; j++) {
792 im = &(ic->methods[j]);
794 /* skip `<clinit>' and `<init>' */
796 if ((im->name == utf_clinit) || (im->name == utf_init))
799 for (tc = c; tc != NULL; tc = tc->super.cls) {
800 for (k = 0; k < tc->methodscount; k++) {
801 if (method_canoverwrite(im, &(tc->methods[k])))
802 goto noabstractmethod2;
806 /* Copy the method found into the new c->methods
807 array and tag it as miranda-method. */
809 am = &(c->methods[c->methodscount]);
812 MCOPY(am, im, methodinfo, 1);
814 am->vftblindex = (vftbllength++);
816 am->flags |= ACC_MIRANDA;
824 RT_TIMING_GET_TIME(time_abstract);
827 #if defined(ENABLE_STATISTICS)
830 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
833 /* compute interfacetable length */
835 interfacetablelength = 0;
837 for (tc = c; tc != NULL; tc = tc->super.cls) {
838 for (i = 0; i < tc->interfacescount; i++) {
839 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
841 if (h > interfacetablelength)
842 interfacetablelength = h;
845 RT_TIMING_GET_TIME(time_compute_iftbl);
847 /* allocate virtual function table */
849 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
850 sizeof(methodptr) * (vftbllength - 1) +
851 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
852 v = (vftbl_t *) (((methodptr *) v) +
853 (interfacetablelength - 1) * (interfacetablelength > 1));
857 v->vftbllength = vftbllength;
858 v->interfacetablelength = interfacetablelength;
859 v->arraydesc = arraydesc;
861 /* store interface index in vftbl */
863 if (c->flags & ACC_INTERFACE)
864 v->baseval = -(c->index);
866 /* copy virtual function table of super class */
868 for (i = 0; i < supervftbllength; i++)
869 v->table[i] = super->vftbl->table[i];
871 /* Fill the remaining vftbl slots with the AbstractMethodError
872 stub (all after the super class slots, because they are already
875 for (; i < vftbllength; i++) {
876 #if defined(ENABLE_JIT)
877 # if defined(ENABLE_INTRP)
879 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
882 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
884 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
888 /* add method stubs into virtual function table */
890 for (i = 0; i < c->methodscount; i++) {
891 methodinfo *m = &(c->methods[i]);
893 assert(m->stubroutine == NULL);
895 /* Don't create a compiler stub for abstract methods as they
896 throw an AbstractMethodError with the default stub in the
897 vftbl. This entry is simply copied by sub-classes. */
899 if (m->flags & ACC_ABSTRACT)
902 #if defined(ENABLE_JIT)
903 # if defined(ENABLE_INTRP)
905 m->stubroutine = intrp_createcompilerstub(m);
908 m->stubroutine = createcompilerstub(m);
910 m->stubroutine = intrp_createcompilerstub(m);
913 /* static methods are not in the vftbl */
915 if (m->flags & ACC_STATIC)
918 /* insert the stubroutine into the vftbl */
920 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
922 RT_TIMING_GET_TIME(time_fill_vftbl);
924 /* compute instance size and offset of each field */
926 for (i = 0; i < c->fieldscount; i++) {
928 fieldinfo *f = &(c->fields[i]);
930 if (!(f->flags & ACC_STATIC)) {
931 dsize = descriptor_typesize(f->parseddesc);
933 /* On i386 we only align to 4 bytes even for double and s8. */
934 /* This matches what gcc does for struct members. We must */
935 /* do the same as gcc here because the offsets in native */
936 /* header structs like java_lang_Double must match the offsets */
937 /* of the Java fields (eg. java.lang.Double.value). */
938 #if defined(__I386__)
939 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
941 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
944 f->offset = c->instancesize;
945 c->instancesize += dsize;
948 RT_TIMING_GET_TIME(time_offsets);
950 /* initialize interfacetable and interfacevftbllength */
952 v->interfacevftbllength = MNEW(s4, interfacetablelength);
954 #if defined(ENABLE_STATISTICS)
956 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
959 for (i = 0; i < interfacetablelength; i++) {
960 v->interfacevftbllength[i] = 0;
961 v->interfacetable[-i] = NULL;
966 for (tc = c; tc != NULL; tc = tc->super.cls)
967 for (i = 0; i < tc->interfacescount; i++)
968 if (!linker_addinterface(c, tc->interfaces[i].cls))
971 RT_TIMING_GET_TIME(time_fill_iftbl);
973 /* add finalizer method (not for java.lang.Object) */
978 fi = class_findmethod(c, utf_finalize, utf_void__void);
981 if (!(fi->flags & ACC_STATIC))
984 RT_TIMING_GET_TIME(time_finalizer);
988 linker_compute_subclasses(c);
990 RT_TIMING_GET_TIME(time_subclasses);
992 /* revert the linking state and class is linked */
994 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
998 /* XXX must this also be done in case of exception? */
1000 while (worklist != NULL) {
1001 method_worklist *wi = worklist;
1003 worklist = worklist->next;
1005 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
1006 jit_invalidate_code(wi->m);
1008 /* XXX put worklist into dump memory? */
1009 FREE(wi, method_worklist);
1012 #if !defined(NDEBUG)
1014 log_message_class("Linking done class: ", c);
1017 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1018 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1019 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1020 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1021 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1022 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1023 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1024 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1025 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1027 /* just return c to show that we didn't had a problem */
1033 /* link_array ******************************************************************
1035 This function is called by link_class to create the arraydescriptor
1038 This function returns NULL if the array cannot be linked because
1039 the component type has not been linked yet.
1041 *******************************************************************************/
1043 static arraydescriptor *link_array(classinfo *c)
1047 arraydescriptor *desc;
1052 namelen = c->name->blength;
1054 /* Check the component type */
1056 switch (c->name->text[1]) {
1058 /* c is an array of arrays. */
1059 u = utf_new(c->name->text + 1, namelen - 1);
1060 if (!(comp = load_class_from_classloader(u, c->classloader)))
1065 /* c is an array of objects. */
1066 u = utf_new(c->name->text + 2, namelen - 3);
1067 if (!(comp = load_class_from_classloader(u, c->classloader)))
1072 /* If the component type has not been linked, link it now */
1074 assert(!comp || (comp->state & CLASS_LOADED));
1076 if (comp && !(comp->state & CLASS_LINKED))
1077 if (!link_class(comp))
1080 /* Allocate the arraydescriptor */
1082 desc = NEW(arraydescriptor);
1085 /* c is an array of references */
1086 desc->arraytype = ARRAYTYPE_OBJECT;
1087 desc->componentsize = sizeof(void*);
1088 desc->dataoffset = OFFSET(java_objectarray, data);
1090 compvftbl = comp->vftbl;
1093 log_text("Component class has no vftbl");
1097 desc->componentvftbl = compvftbl;
1099 if (compvftbl->arraydesc) {
1100 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1102 if (compvftbl->arraydesc->dimension >= 255) {
1103 log_text("Creating array of dimension >255");
1107 desc->dimension = compvftbl->arraydesc->dimension + 1;
1108 desc->elementtype = compvftbl->arraydesc->elementtype;
1111 desc->elementvftbl = compvftbl;
1112 desc->dimension = 1;
1113 desc->elementtype = ARRAYTYPE_OBJECT;
1117 /* c is an array of a primitive type */
1118 switch (c->name->text[1]) {
1120 desc->arraytype = ARRAYTYPE_BOOLEAN;
1121 desc->dataoffset = OFFSET(java_booleanarray,data);
1122 desc->componentsize = sizeof(u1);
1126 desc->arraytype = ARRAYTYPE_BYTE;
1127 desc->dataoffset = OFFSET(java_bytearray,data);
1128 desc->componentsize = sizeof(u1);
1132 desc->arraytype = ARRAYTYPE_CHAR;
1133 desc->dataoffset = OFFSET(java_chararray,data);
1134 desc->componentsize = sizeof(u2);
1138 desc->arraytype = ARRAYTYPE_DOUBLE;
1139 desc->dataoffset = OFFSET(java_doublearray,data);
1140 desc->componentsize = sizeof(double);
1144 desc->arraytype = ARRAYTYPE_FLOAT;
1145 desc->dataoffset = OFFSET(java_floatarray,data);
1146 desc->componentsize = sizeof(float);
1150 desc->arraytype = ARRAYTYPE_INT;
1151 desc->dataoffset = OFFSET(java_intarray,data);
1152 desc->componentsize = sizeof(s4);
1156 desc->arraytype = ARRAYTYPE_LONG;
1157 desc->dataoffset = OFFSET(java_longarray,data);
1158 desc->componentsize = sizeof(s8);
1162 desc->arraytype = ARRAYTYPE_SHORT;
1163 desc->dataoffset = OFFSET(java_shortarray,data);
1164 desc->componentsize = sizeof(s2);
1168 *exceptionptr = new_noclassdeffounderror(c->name);
1172 desc->componentvftbl = NULL;
1173 desc->elementvftbl = NULL;
1174 desc->dimension = 1;
1175 desc->elementtype = desc->arraytype;
1182 /* linker_compute_subclasses ***************************************************
1186 *******************************************************************************/
1188 static void linker_compute_subclasses(classinfo *c)
1190 #if defined(ENABLE_THREADS)
1194 if (!(c->flags & ACC_INTERFACE)) {
1199 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1200 c->nextsub = c->super.cls->sub;
1201 c->super.cls->sub = c;
1206 /* compute class values */
1208 linker_compute_class_values(class_java_lang_Object);
1210 #if defined(ENABLE_THREADS)
1216 /* linker_compute_class_values *************************************************
1220 *******************************************************************************/
1222 static void linker_compute_class_values(classinfo *c)
1226 c->vftbl->baseval = ++classvalue;
1231 linker_compute_class_values(subs);
1233 subs = subs->nextsub;
1236 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1240 /* linker_addinterface *********************************************************
1242 Is needed by link_class for adding a VTBL to a class. All
1243 interfaces implemented by ic are added as well.
1246 true.........everything ok
1247 false........an exception has been thrown
1249 *******************************************************************************/
1251 static bool linker_addinterface(classinfo *c, classinfo *ic)
1262 if (i >= v->interfacetablelength)
1263 vm_abort("Internal error: interfacetable overflow");
1265 /* if this interface has already been added, return immediately */
1267 if (v->interfacetable[-i] != NULL)
1270 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1271 v->interfacevftbllength[i] = 1;
1272 v->interfacetable[-i] = MNEW(methodptr, 1);
1273 v->interfacetable[-i][0] = NULL;
1276 v->interfacevftbllength[i] = ic->methodscount;
1277 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1279 #if defined(ENABLE_STATISTICS)
1281 count_vftbl_len += sizeof(methodptr) *
1282 (ic->methodscount + (ic->methodscount == 0));
1285 for (j = 0; j < ic->methodscount; j++) {
1286 for (sc = c; sc != NULL; sc = sc->super.cls) {
1287 for (k = 0; k < sc->methodscount; k++) {
1288 m = &(sc->methods[k]);
1290 if (method_canoverwrite(m, &(ic->methods[j]))) {
1291 /* method m overwrites the (abstract) method */
1292 #if defined(ENABLE_VERIFIER)
1293 /* Add loading constraints (for the more
1294 general types of the method
1296 if (!classcache_add_constraints_for_params(
1297 c->classloader, ic->classloader,
1304 /* XXX taken from gcj */
1305 /* check for ACC_STATIC: IncompatibleClassChangeError */
1307 /* check for !ACC_PUBLIC: IllegalAccessError */
1309 /* check for ACC_ABSTRACT: AbstracMethodError,
1310 not sure about that one */
1312 v->interfacetable[-i][j] = v->table[m->vftblindex];
1318 /* If no method was found, insert the AbstractMethodError
1321 #if defined(ENABLE_JIT)
1322 # if defined(ENABLE_INTRP)
1324 v->interfacetable[-i][j] =
1325 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1328 v->interfacetable[-i][j] =
1329 (methodptr) (ptrint) &asm_abstractmethoderror;
1331 v->interfacetable[-i][j] =
1332 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1340 /* add superinterfaces of this interface */
1342 for (j = 0; j < ic->interfacescount; j++)
1343 if (!linker_addinterface(c, ic->interfaces[j].cls))
1352 /* class_highestinterface ******************************************************
1354 Used by the function link_class to determine the amount of memory
1355 needed for the interface table.
1357 *******************************************************************************/
1359 static s4 class_highestinterface(classinfo *c)
1365 /* check for ACC_INTERFACE bit already done in link_class_intern */
1369 for (i = 0; i < c->interfacescount; i++) {
1370 h2 = class_highestinterface(c->interfaces[i].cls);
1381 * These are local overrides for various environment variables in Emacs.
1382 * Please do not remove this and leave it at the end of the file, where
1383 * Emacs will automagically detect them.
1384 * ---------------------------------------------------------------------
1387 * indent-tabs-mode: t
1391 * vim:noexpandtab:sw=4:ts=4: