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 5056 2006-06-28 21:01:21Z edwin $
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
50 #include "vm/classcache.h"
51 #include "vm/exceptions.h"
52 #include "vm/loader.h"
53 #include "vm/options.h"
54 #include "vm/resolve.h"
55 #include "vm/statistics.h"
56 #include "vm/stringlocal.h"
57 #include "vm/access.h"
58 #include "vm/rt-timing.h"
60 #include "vm/jit/asmpart.h"
63 /* global variables ***********************************************************/
65 static s4 interfaceindex; /* sequential numbering of interfaces */
69 /* primitivetype_table *********************************************************
71 Structure for primitive classes: contains the class for wrapping
72 the primitive type, the primitive class, the name of the class for
73 wrapping, the one character type signature and the name of the
76 CAUTION: Don't change the order of the types. This table is indexed
77 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
79 *******************************************************************************/
81 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
82 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
83 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
84 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
85 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
86 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
87 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
88 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
89 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
90 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
91 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
92 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
96 /* private functions **********************************************************/
98 static bool link_primitivetype_table(void);
99 static classinfo *link_class_intern(classinfo *c);
100 static arraydescriptor *link_array(classinfo *c);
101 static void linker_compute_class_values(classinfo *c);
102 static void linker_compute_subclasses(classinfo *c);
103 static bool linker_addinterface(classinfo *c, classinfo *ic);
104 static s4 class_highestinterface(classinfo *c);
107 /* linker_init *****************************************************************
109 Initializes the linker subsystem.
111 *******************************************************************************/
113 bool linker_init(void)
115 /* reset interface index */
119 /* link java.lang.Class as first class of the system, because we
120 need it's vftbl for all other classes so we can use a class as
123 if (!link_class(class_java_lang_Class))
126 /* now set the header.vftbl of all classes which were created
127 before java.lang.Class was linked */
129 class_postset_header_vftbl();
132 /* link important system classes */
134 if (!link_class(class_java_lang_Object))
137 if (!link_class(class_java_lang_String))
140 if (!link_class(class_java_lang_Cloneable))
143 if (!link_class(class_java_io_Serializable))
147 /* link classes for wrapping primitive types */
149 if (!link_class(class_java_lang_Void))
152 if (!link_class(class_java_lang_Boolean))
155 if (!link_class(class_java_lang_Byte))
158 if (!link_class(class_java_lang_Character))
161 if (!link_class(class_java_lang_Short))
164 if (!link_class(class_java_lang_Integer))
167 if (!link_class(class_java_lang_Long))
170 if (!link_class(class_java_lang_Float))
173 if (!link_class(class_java_lang_Double))
177 /* load some other important classes */
179 if (!link_class(class_java_lang_ClassLoader))
182 if (!link_class(class_java_lang_SecurityManager))
185 if (!link_class(class_java_lang_System))
188 if (!link_class(class_java_lang_Thread))
191 if (!link_class(class_java_lang_ThreadGroup))
194 if (!link_class(class_java_lang_VMThread))
198 /* some classes which may be used more often */
200 if (!link_class(class_java_lang_StackTraceElement))
203 if (!link_class(class_java_lang_reflect_Constructor))
206 if (!link_class(class_java_lang_reflect_Field))
209 if (!link_class(class_java_lang_reflect_Method))
212 if (!link_class(class_java_security_PrivilegedAction))
215 if (!link_class(class_java_util_Vector))
218 if (!link_class(arrayclass_java_lang_Object))
222 /* create pseudo classes used by the typechecker */
224 /* pseudo class for Arraystubs (extends java.lang.Object) */
226 pseudo_class_Arraystub =
227 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
228 pseudo_class_Arraystub->state |= CLASS_LOADED;
229 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
230 pseudo_class_Arraystub->interfacescount = 2;
231 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
232 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
233 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
235 if (!classcache_store_unique(pseudo_class_Arraystub)) {
236 log_text("could not cache pseudo_class_Arraystub");
240 if (!link_class(pseudo_class_Arraystub))
243 /* pseudo class representing the null type */
245 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
246 pseudo_class_Null->state |= CLASS_LOADED;
247 pseudo_class_Null->super.cls = class_java_lang_Object;
249 if (!classcache_store_unique(pseudo_class_Null)) {
250 log_text("could not cache pseudo_class_Null");
254 if (!link_class(pseudo_class_Null))
257 /* pseudo class representing new uninitialized objects */
259 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
260 pseudo_class_New->state |= CLASS_LOADED;
261 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
262 pseudo_class_New->super.cls = class_java_lang_Object;
264 if (!classcache_store_unique(pseudo_class_New)) {
265 log_text("could not cache pseudo_class_New");
269 /* create classes representing primitive types */
271 if (!link_primitivetype_table())
275 /* Correct vftbl-entries (retarded loading and linking of class */
276 /* java/lang/String). */
278 stringtable_update();
284 /* link_primitivetype_table ****************************************************
286 Create classes representing primitive types.
288 *******************************************************************************/
290 static bool link_primitivetype_table(void)
296 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
299 if (!primitivetype_table[i].name)
302 /* create primitive class */
304 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
306 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
308 /* prevent loader from loading primitive class */
310 c->state |= CLASS_LOADED;
312 /* INFO: don't put primitive classes into the classcache */
317 primitivetype_table[i].class_primitive = c;
319 /* create class for wrapping the primitive type */
321 u = utf_new_char(primitivetype_table[i].wrapname);
323 if (!(c = load_class_bootstrap(u)))
326 primitivetype_table[i].class_wrap = c;
328 /* create the primitive array class */
330 if (primitivetype_table[i].arrayname) {
331 u = utf_new_char(primitivetype_table[i].arrayname);
332 c = class_create_classinfo(u);
333 c = load_newly_created_array(c, NULL);
337 primitivetype_table[i].arrayclass = c;
339 assert(c->state & CLASS_LOADED);
341 if (!(c->state & CLASS_LINKED))
345 primitivetype_table[i].arrayvftbl = c->vftbl;
353 /* link_class ******************************************************************
355 Wrapper function for link_class_intern to ease monitor enter/exit
356 and exception handling.
358 *******************************************************************************/
360 classinfo *link_class(classinfo *c)
363 #if defined(ENABLE_RT_TIMING)
364 struct timespec time_start, time_end;
367 RT_TIMING_GET_TIME(time_start);
370 exceptions_throw_nullpointerexception();
374 #if defined(ENABLE_THREADS)
375 /* enter a monitor on the class */
377 builtin_monitorenter((java_objectheader *) c);
380 /* maybe the class is already linked */
382 if (c->state & CLASS_LINKED) {
383 #if defined(ENABLE_THREADS)
384 builtin_monitorexit((java_objectheader *) c);
390 #if defined(ENABLE_STATISTICS)
393 if (opt_getcompilingtime)
394 compilingtime_stop();
396 if (opt_getloadingtime)
400 /* call the internal function */
402 r = link_class_intern(c);
404 /* if return value is NULL, we had a problem and the class is not linked */
407 c->state &= ~CLASS_LINKING;
409 #if defined(ENABLE_STATISTICS)
412 if (opt_getloadingtime)
415 if (opt_getcompilingtime)
416 compilingtime_start();
419 #if defined(ENABLE_THREADS)
420 /* leave the monitor */
422 builtin_monitorexit((java_objectheader *) c);
425 RT_TIMING_GET_TIME(time_end);
427 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
433 /* link_class_intern ***********************************************************
435 Tries to link a class. The function calculates the length in bytes
436 that an instance of this class requires as well as the VTBL for
437 methods and interface methods.
439 *******************************************************************************/
441 static classinfo *link_class_intern(classinfo *c)
443 classinfo *super; /* super class */
444 classinfo *tc; /* temporary class variable */
445 s4 supervftbllength; /* vftbllegnth of super class */
446 s4 vftbllength; /* vftbllength of current class */
447 s4 interfacetablelength; /* interface table length */
448 vftbl_t *v; /* vftbl of current class */
449 s4 i,j; /* interface/method/field counter */
450 arraydescriptor *arraydesc; /* descriptor for array classes */
451 #if defined(ENABLE_RT_TIMING)
452 struct timespec time_start, time_resolving, time_compute_vftbl,
453 time_abstract, time_compute_iftbl, time_fill_vftbl,
454 time_offsets, time_fill_iftbl, time_finalizer,
455 time_exceptions, time_subclasses;
458 RT_TIMING_GET_TIME(time_start);
460 /* the class is already linked */
462 if (c->state & CLASS_LINKED)
467 log_message_class("Linking class: ", c);
470 /* the class must be loaded */
472 /* XXX should this be a specific exception? */
473 assert(c->state & CLASS_LOADED);
475 /* cache the self-reference of this class */
476 /* we do this for cases where the defining loader of the class */
477 /* has not yet been recorded as an initiating loader for the class */
478 /* this is needed so subsequent code can assume that self-refs */
479 /* will always resolve lazily */
480 /* No need to do it for the bootloader - it is always registered */
481 /* as initiating loader for the classes it loads. */
483 classcache_store(c->classloader,c,false);
485 /* this class is currently linking */
487 c->state |= CLASS_LINKING;
491 /* check interfaces */
493 for (i = 0; i < c->interfacescount; i++) {
494 /* resolve this super interface */
496 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
500 c->interfaces[i].cls = tc;
502 /* detect circularity */
506 new_exception_utfmessage(string_java_lang_ClassCircularityError,
511 assert(tc->state & CLASS_LOADED);
513 if (!(tc->flags & ACC_INTERFACE)) {
515 new_exception_message(string_java_lang_IncompatibleClassChangeError,
516 "Implementing class");
520 if (!(tc->state & CLASS_LINKED))
525 /* check super class */
529 if (c->super.any == NULL) { /* class java.lang.Object */
531 c->instancesize = sizeof(java_objectheader);
533 vftbllength = supervftbllength = 0;
538 /* resolve super class */
540 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
543 c->super.cls = super;
545 /* detect circularity */
549 new_exception_utfmessage(string_java_lang_ClassCircularityError,
554 assert(super->state & CLASS_LOADED);
556 if (super->flags & ACC_INTERFACE) {
557 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
558 log_text("Interface specified as super class");
562 /* Don't allow extending final classes */
564 if (super->flags & ACC_FINAL) {
566 new_exception_message(string_java_lang_VerifyError,
567 "Cannot inherit from final class");
571 /* link the superclass if necessary */
573 if (!(super->state & CLASS_LINKED))
574 if (!link_class(super))
577 /* OR the ACC_CLASS_HAS_POINTERS flag */
579 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
581 /* handle array classes */
583 if (c->name->text[0] == '[')
584 if (!(arraydesc = link_array(c)))
587 if (c->flags & ACC_INTERFACE)
588 c->index = interfaceindex++;
590 c->index = super->index + 1;
592 c->instancesize = super->instancesize;
594 vftbllength = supervftbllength = super->vftbl->vftbllength;
596 c->finalizer = super->finalizer;
598 RT_TIMING_GET_TIME(time_resolving);
601 /* compute vftbl length */
603 for (i = 0; i < c->methodscount; i++) {
604 methodinfo *m = &(c->methods[i]);
606 if (!(m->flags & ACC_STATIC)) { /* is instance method */
612 for (j = 0; j < tc->methodscount; j++) {
613 if (method_canoverwrite(m, &(tc->methods[j]))) {
614 if (tc->methods[j].flags & ACC_PRIVATE)
615 goto notfoundvftblindex;
617 /* package-private methods in other packages */
618 /* must not be overridden */
619 /* (see Java Language Specification 8.4.8.1) */
620 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
621 && !SAME_PACKAGE(c,tc) )
623 goto notfoundvftblindex;
626 if (tc->methods[j].flags & ACC_FINAL) {
627 /* class a overrides final method . */
629 new_exception(string_java_lang_VerifyError);
633 /* method m overwrites method j of class tc */
635 #if defined(ENABLE_VERIFIER)
636 /* Add loading constraints (for the more general */
637 /* types of method tc->methods[j]). -- */
638 /* Not for <init>, as it is not invoked virtually. */
639 if ((m->name != utf_init)
640 && !classcache_add_constraints_for_params(
641 c->classloader, tc->classloader,
648 m->vftblindex = tc->methods[j].vftblindex;
649 goto foundvftblindex;
657 m->vftblindex = (vftbllength++);
662 RT_TIMING_GET_TIME(time_compute_vftbl);
665 /* Check all interfaces of an abstract class (maybe be an
666 interface too) for unimplemented methods. Such methods are
667 called miranda-methods and are marked with the ACC_MIRANDA
668 flag. VMClass.getDeclaredMethods does not return such
671 if (c->flags & ACC_ABSTRACT) {
674 s4 abstractmethodscount;
678 abstractmethodscount = 0;
680 /* check all interfaces of the abstract class */
682 for (i = 0; i < c->interfacescount; i++) {
683 ic = c->interfaces[i].cls;
685 for (j = 0; j < ic->methodscount; j++) {
686 im = &(ic->methods[j]);
688 /* skip `<clinit>' and `<init>' */
690 if ((im->name == utf_clinit) || (im->name == utf_init))
693 for (tc = c; tc != NULL; tc = tc->super.cls) {
694 for (k = 0; k < tc->methodscount; k++) {
695 if (method_canoverwrite(im, &(tc->methods[k])))
696 goto noabstractmethod;
700 abstractmethodscount++;
707 if (abstractmethodscount > 0) {
710 /* reallocate methods memory */
712 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
713 c->methodscount + abstractmethodscount);
715 for (i = 0; i < c->interfacescount; i++) {
716 ic = c->interfaces[i].cls;
718 for (j = 0; j < ic->methodscount; j++) {
719 im = &(ic->methods[j]);
721 /* skip `<clinit>' and `<init>' */
723 if ((im->name == utf_clinit) || (im->name == utf_init))
726 for (tc = c; tc != NULL; tc = tc->super.cls) {
727 for (k = 0; k < tc->methodscount; k++) {
728 if (method_canoverwrite(im, &(tc->methods[k])))
729 goto noabstractmethod2;
733 /* Copy the method found into the new c->methods
734 array and tag it as miranda-method. */
736 am = &(c->methods[c->methodscount]);
739 MCOPY(am, im, methodinfo, 1);
741 am->vftblindex = (vftbllength++);
743 am->flags |= ACC_MIRANDA;
751 RT_TIMING_GET_TIME(time_abstract);
754 #if defined(ENABLE_STATISTICS)
757 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
760 /* compute interfacetable length */
762 interfacetablelength = 0;
764 for (tc = c; tc != NULL; tc = tc->super.cls) {
765 for (i = 0; i < tc->interfacescount; i++) {
766 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
768 if (h > interfacetablelength)
769 interfacetablelength = h;
772 RT_TIMING_GET_TIME(time_compute_iftbl);
774 /* allocate virtual function table */
776 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
777 sizeof(methodptr) * (vftbllength - 1) +
778 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
779 v = (vftbl_t *) (((methodptr *) v) +
780 (interfacetablelength - 1) * (interfacetablelength > 1));
784 v->vftbllength = vftbllength;
785 v->interfacetablelength = interfacetablelength;
786 v->arraydesc = arraydesc;
788 /* store interface index in vftbl */
790 if (c->flags & ACC_INTERFACE)
791 v->baseval = -(c->index);
793 /* copy virtual function table of super class */
795 for (i = 0; i < supervftbllength; i++)
796 v->table[i] = super->vftbl->table[i];
798 /* Fill the remaining vftbl slots with the AbstractMethodError
799 stub (all after the super class slots, because they are already
802 for (; i < vftbllength; i++)
803 v->table[i] = &asm_abstractmethoderror;
805 /* add method stubs into virtual function table */
807 for (i = 0; i < c->methodscount; i++) {
808 methodinfo *m = &(c->methods[i]);
810 if (m->flags & ACC_ABSTRACT)
813 /* Methods in ABSTRACT classes from interfaces maybe already
814 have a stubroutine. */
816 if (m->stubroutine == NULL) {
817 #if defined(ENABLE_JIT)
818 # if defined(ENABLE_INTRP)
820 m->stubroutine = intrp_createcompilerstub(m);
823 m->stubroutine = createcompilerstub(m);
825 m->stubroutine = intrp_createcompilerstub(m);
829 if (!(m->flags & ACC_STATIC))
830 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
832 RT_TIMING_GET_TIME(time_fill_vftbl);
834 /* compute instance size and offset of each field */
836 for (i = 0; i < c->fieldscount; i++) {
838 fieldinfo *f = &(c->fields[i]);
840 if (!(f->flags & ACC_STATIC)) {
841 dsize = descriptor_typesize(f->parseddesc);
843 /* On i386 we only align to 4 bytes even for double and s8. */
844 /* This matches what gcc does for struct members. We must */
845 /* do the same as gcc here because the offsets in native */
846 /* header structs like java_lang_Double must match the offsets */
847 /* of the Java fields (eg. java.lang.Double.value). */
848 #if defined(__I386__)
849 c->instancesize = ALIGN(c->instancesize, 4);
851 c->instancesize = ALIGN(c->instancesize, dsize);
854 f->offset = c->instancesize;
855 c->instancesize += dsize;
858 RT_TIMING_GET_TIME(time_offsets);
860 /* initialize interfacetable and interfacevftbllength */
862 v->interfacevftbllength = MNEW(s4, interfacetablelength);
864 #if defined(ENABLE_STATISTICS)
866 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
869 for (i = 0; i < interfacetablelength; i++) {
870 v->interfacevftbllength[i] = 0;
871 v->interfacetable[-i] = NULL;
876 for (tc = c; tc != NULL; tc = tc->super.cls)
877 for (i = 0; i < tc->interfacescount; i++)
878 if (!linker_addinterface(c, tc->interfaces[i].cls))
881 RT_TIMING_GET_TIME(time_fill_iftbl);
883 /* add finalizer method (not for java.lang.Object) */
888 fi = class_findmethod(c, utf_finalize, utf_void__void);
891 if (!(fi->flags & ACC_STATIC))
894 RT_TIMING_GET_TIME(time_finalizer);
896 /* resolve exception class references */
898 for (i = 0; i < c->methodscount; i++) {
899 methodinfo *m = &(c->methods[i]);
901 for (j = 0; j < m->exceptiontablelength; j++) {
902 if (!m->exceptiontable[j].catchtype.any)
904 if (!resolve_classref_or_classinfo(NULL,
905 m->exceptiontable[j].catchtype,
906 resolveEager, true, false,
907 &(m->exceptiontable[j].catchtype.cls)))
911 RT_TIMING_GET_TIME(time_exceptions);
915 linker_compute_subclasses(c);
917 RT_TIMING_GET_TIME(time_subclasses);
919 /* revert the linking state and class is linked */
921 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
925 log_message_class("Linking done class: ", c);
928 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
929 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
930 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
931 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
932 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
933 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
934 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
935 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
936 RT_TIMING_TIME_DIFF(time_finalizer ,time_exceptions ,RT_TIMING_LINK_EXCEPTS);
937 RT_TIMING_TIME_DIFF(time_exceptions ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
939 /* just return c to show that we didn't had a problem */
945 /* link_array ******************************************************************
947 This function is called by link_class to create the arraydescriptor
950 This function returns NULL if the array cannot be linked because
951 the component type has not been linked yet.
953 *******************************************************************************/
955 static arraydescriptor *link_array(classinfo *c)
959 arraydescriptor *desc;
964 namelen = c->name->blength;
966 /* Check the component type */
968 switch (c->name->text[1]) {
970 /* c is an array of arrays. */
971 u = utf_new(c->name->text + 1, namelen - 1);
972 if (!(comp = load_class_from_classloader(u, c->classloader)))
977 /* c is an array of objects. */
978 u = utf_new(c->name->text + 2, namelen - 3);
979 if (!(comp = load_class_from_classloader(u, c->classloader)))
984 /* If the component type has not been linked, link it now */
986 assert(!comp || (comp->state & CLASS_LOADED));
988 if (comp && !(comp->state & CLASS_LINKED))
989 if (!link_class(comp))
992 /* Allocate the arraydescriptor */
994 desc = NEW(arraydescriptor);
997 /* c is an array of references */
998 desc->arraytype = ARRAYTYPE_OBJECT;
999 desc->componentsize = sizeof(void*);
1000 desc->dataoffset = OFFSET(java_objectarray, data);
1002 compvftbl = comp->vftbl;
1005 log_text("Component class has no vftbl");
1009 desc->componentvftbl = compvftbl;
1011 if (compvftbl->arraydesc) {
1012 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1014 if (compvftbl->arraydesc->dimension >= 255) {
1015 log_text("Creating array of dimension >255");
1019 desc->dimension = compvftbl->arraydesc->dimension + 1;
1020 desc->elementtype = compvftbl->arraydesc->elementtype;
1023 desc->elementvftbl = compvftbl;
1024 desc->dimension = 1;
1025 desc->elementtype = ARRAYTYPE_OBJECT;
1029 /* c is an array of a primitive type */
1030 switch (c->name->text[1]) {
1032 desc->arraytype = ARRAYTYPE_BOOLEAN;
1033 desc->dataoffset = OFFSET(java_booleanarray,data);
1034 desc->componentsize = sizeof(u1);
1038 desc->arraytype = ARRAYTYPE_BYTE;
1039 desc->dataoffset = OFFSET(java_bytearray,data);
1040 desc->componentsize = sizeof(u1);
1044 desc->arraytype = ARRAYTYPE_CHAR;
1045 desc->dataoffset = OFFSET(java_chararray,data);
1046 desc->componentsize = sizeof(u2);
1050 desc->arraytype = ARRAYTYPE_DOUBLE;
1051 desc->dataoffset = OFFSET(java_doublearray,data);
1052 desc->componentsize = sizeof(double);
1056 desc->arraytype = ARRAYTYPE_FLOAT;
1057 desc->dataoffset = OFFSET(java_floatarray,data);
1058 desc->componentsize = sizeof(float);
1062 desc->arraytype = ARRAYTYPE_INT;
1063 desc->dataoffset = OFFSET(java_intarray,data);
1064 desc->componentsize = sizeof(s4);
1068 desc->arraytype = ARRAYTYPE_LONG;
1069 desc->dataoffset = OFFSET(java_longarray,data);
1070 desc->componentsize = sizeof(s8);
1074 desc->arraytype = ARRAYTYPE_SHORT;
1075 desc->dataoffset = OFFSET(java_shortarray,data);
1076 desc->componentsize = sizeof(s2);
1080 *exceptionptr = new_noclassdeffounderror(c->name);
1084 desc->componentvftbl = NULL;
1085 desc->elementvftbl = NULL;
1086 desc->dimension = 1;
1087 desc->elementtype = desc->arraytype;
1094 /* linker_compute_subclasses ***************************************************
1098 *******************************************************************************/
1100 static void linker_compute_subclasses(classinfo *c)
1102 #if defined(ENABLE_THREADS)
1106 if (!(c->flags & ACC_INTERFACE)) {
1111 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1112 c->nextsub = c->super.cls->sub;
1113 c->super.cls->sub = c;
1118 /* compute class values */
1120 linker_compute_class_values(class_java_lang_Object);
1122 #if defined(ENABLE_THREADS)
1128 /* linker_compute_class_values *************************************************
1132 *******************************************************************************/
1134 static void linker_compute_class_values(classinfo *c)
1138 c->vftbl->baseval = ++classvalue;
1143 linker_compute_class_values(subs);
1145 subs = subs->nextsub;
1148 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1152 /* linker_addinterface *********************************************************
1154 Is needed by link_class for adding a VTBL to a class. All
1155 interfaces implemented by ic are added as well.
1158 true.........everything ok
1159 false........an exception has been thrown
1161 *******************************************************************************/
1163 static bool linker_addinterface(classinfo *c, classinfo *ic)
1174 if (i >= v->interfacetablelength)
1175 vm_abort("Internal error: interfacetable overflow");
1177 /* if this interface has already been added, return immediately */
1179 if (v->interfacetable[-i] != NULL)
1182 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1183 v->interfacevftbllength[i] = 1;
1184 v->interfacetable[-i] = MNEW(methodptr, 1);
1185 v->interfacetable[-i][0] = NULL;
1188 v->interfacevftbllength[i] = ic->methodscount;
1189 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1191 #if defined(ENABLE_STATISTICS)
1193 count_vftbl_len += sizeof(methodptr) *
1194 (ic->methodscount + (ic->methodscount == 0));
1197 for (j = 0; j < ic->methodscount; j++) {
1198 for (sc = c; sc != NULL; sc = sc->super.cls) {
1199 for (k = 0; k < sc->methodscount; k++) {
1200 m = &(sc->methods[k]);
1202 if (method_canoverwrite(m, &(ic->methods[j]))) {
1203 /* method m overwrites the (abstract) method */
1204 #if defined(ENABLE_VERIFIER)
1205 /* Add loading constraints (for the more
1206 general types of the method
1208 if (!classcache_add_constraints_for_params(
1209 c->classloader, ic->classloader,
1216 /* XXX taken from gcj */
1217 /* check for ACC_STATIC: IncompatibleClassChangeError */
1219 /* check for !ACC_PUBLIC: IllegalAccessError */
1221 /* check for ACC_ABSTRACT: AbstracMethodError,
1222 not sure about that one */
1224 v->interfacetable[-i][j] = v->table[m->vftblindex];
1230 /* If no method was found, insert the AbstractMethodError
1233 v->interfacetable[-i][j] = &asm_abstractmethoderror;
1240 /* add superinterfaces of this interface */
1242 for (j = 0; j < ic->interfacescount; j++)
1243 if (!linker_addinterface(c, ic->interfaces[j].cls))
1252 /* class_highestinterface ******************************************************
1254 Used by the function link_class to determine the amount of memory
1255 needed for the interface table.
1257 *******************************************************************************/
1259 static s4 class_highestinterface(classinfo *c)
1265 /* check for ACC_INTERFACE bit already done in link_class_intern */
1269 for (i = 0; i < c->interfacescount; i++) {
1270 h2 = class_highestinterface(c->interfaces[i].cls);
1281 * These are local overrides for various environment variables in Emacs.
1282 * Please do not remove this and leave it at the end of the file, where
1283 * Emacs will automagically detect them.
1284 * ---------------------------------------------------------------------
1287 * indent-tabs-mode: t
1291 * vim:noexpandtab:sw=4:ts=4: