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 5123 2006-07-12 21:45:34Z twisti $
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 /* global variables ***********************************************************/
71 static s4 interfaceindex; /* sequential numbering of interfaces */
75 /* primitivetype_table *********************************************************
77 Structure for primitive classes: contains the class for wrapping
78 the primitive type, the primitive class, the name of the class for
79 wrapping, the one character type signature and the name of the
82 CAUTION: Don't change the order of the types. This table is indexed
83 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
85 *******************************************************************************/
87 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
88 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
89 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
90 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
91 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
92 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
93 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
94 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
95 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
96 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
97 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
98 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
102 /* private functions **********************************************************/
104 static bool link_primitivetype_table(void);
105 static classinfo *link_class_intern(classinfo *c);
106 static arraydescriptor *link_array(classinfo *c);
107 static void linker_compute_class_values(classinfo *c);
108 static void linker_compute_subclasses(classinfo *c);
109 static bool linker_addinterface(classinfo *c, classinfo *ic);
110 static s4 class_highestinterface(classinfo *c);
113 /* linker_init *****************************************************************
115 Initializes the linker subsystem.
117 *******************************************************************************/
119 bool linker_init(void)
121 /* reset interface index */
125 /* link java.lang.Class as first class of the system, because we
126 need it's vftbl for all other classes so we can use a class as
129 if (!link_class(class_java_lang_Class))
132 /* now set the header.vftbl of all classes which were created
133 before java.lang.Class was linked */
135 class_postset_header_vftbl();
138 /* link important system classes */
140 if (!link_class(class_java_lang_Object))
143 if (!link_class(class_java_lang_String))
146 if (!link_class(class_java_lang_Cloneable))
149 if (!link_class(class_java_io_Serializable))
153 /* link classes for wrapping primitive types */
155 if (!link_class(class_java_lang_Void))
158 if (!link_class(class_java_lang_Boolean))
161 if (!link_class(class_java_lang_Byte))
164 if (!link_class(class_java_lang_Character))
167 if (!link_class(class_java_lang_Short))
170 if (!link_class(class_java_lang_Integer))
173 if (!link_class(class_java_lang_Long))
176 if (!link_class(class_java_lang_Float))
179 if (!link_class(class_java_lang_Double))
183 /* load some other important classes */
185 if (!link_class(class_java_lang_ClassLoader))
188 if (!link_class(class_java_lang_SecurityManager))
191 if (!link_class(class_java_lang_System))
194 if (!link_class(class_java_lang_Thread))
197 if (!link_class(class_java_lang_ThreadGroup))
200 if (!link_class(class_java_lang_VMThread))
204 /* some classes which may be used more often */
206 if (!link_class(class_java_lang_StackTraceElement))
209 if (!link_class(class_java_lang_reflect_Constructor))
212 if (!link_class(class_java_lang_reflect_Field))
215 if (!link_class(class_java_lang_reflect_Method))
218 if (!link_class(class_java_security_PrivilegedAction))
221 if (!link_class(class_java_util_Vector))
224 if (!link_class(arrayclass_java_lang_Object))
228 /* create pseudo classes used by the typechecker */
230 /* pseudo class for Arraystubs (extends java.lang.Object) */
232 pseudo_class_Arraystub =
233 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
234 pseudo_class_Arraystub->state |= CLASS_LOADED;
235 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
236 pseudo_class_Arraystub->interfacescount = 2;
237 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
238 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
239 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
241 if (!classcache_store_unique(pseudo_class_Arraystub)) {
242 log_text("could not cache pseudo_class_Arraystub");
246 if (!link_class(pseudo_class_Arraystub))
249 /* pseudo class representing the null type */
251 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
252 pseudo_class_Null->state |= CLASS_LOADED;
253 pseudo_class_Null->super.cls = class_java_lang_Object;
255 if (!classcache_store_unique(pseudo_class_Null)) {
256 log_text("could not cache pseudo_class_Null");
260 if (!link_class(pseudo_class_Null))
263 /* pseudo class representing new uninitialized objects */
265 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
266 pseudo_class_New->state |= CLASS_LOADED;
267 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
268 pseudo_class_New->super.cls = class_java_lang_Object;
270 if (!classcache_store_unique(pseudo_class_New)) {
271 log_text("could not cache pseudo_class_New");
275 /* create classes representing primitive types */
277 if (!link_primitivetype_table())
281 /* Correct vftbl-entries (retarded loading and linking of class */
282 /* java/lang/String). */
284 stringtable_update();
290 /* link_primitivetype_table ****************************************************
292 Create classes representing primitive types.
294 *******************************************************************************/
296 static bool link_primitivetype_table(void)
302 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
305 if (!primitivetype_table[i].name)
308 /* create primitive class */
310 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
312 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
314 /* prevent loader from loading primitive class */
316 c->state |= CLASS_LOADED;
318 /* INFO: don't put primitive classes into the classcache */
323 primitivetype_table[i].class_primitive = c;
325 /* create class for wrapping the primitive type */
327 u = utf_new_char(primitivetype_table[i].wrapname);
329 if (!(c = load_class_bootstrap(u)))
332 primitivetype_table[i].class_wrap = c;
334 /* create the primitive array class */
336 if (primitivetype_table[i].arrayname) {
337 u = utf_new_char(primitivetype_table[i].arrayname);
338 c = class_create_classinfo(u);
339 c = load_newly_created_array(c, NULL);
343 primitivetype_table[i].arrayclass = c;
345 assert(c->state & CLASS_LOADED);
347 if (!(c->state & CLASS_LINKED))
351 primitivetype_table[i].arrayvftbl = c->vftbl;
359 /* link_class ******************************************************************
361 Wrapper function for link_class_intern to ease monitor enter/exit
362 and exception handling.
364 *******************************************************************************/
366 classinfo *link_class(classinfo *c)
369 #if defined(ENABLE_RT_TIMING)
370 struct timespec time_start, time_end;
373 RT_TIMING_GET_TIME(time_start);
376 exceptions_throw_nullpointerexception();
380 LOCK_MONITOR_ENTER(c);
382 /* maybe the class is already linked */
384 if (c->state & CLASS_LINKED) {
385 LOCK_MONITOR_EXIT(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 LOCK_MONITOR_EXIT(c);
421 RT_TIMING_GET_TIME(time_end);
423 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
429 /* link_class_intern ***********************************************************
431 Tries to link a class. The function calculates the length in bytes
432 that an instance of this class requires as well as the VTBL for
433 methods and interface methods.
435 *******************************************************************************/
437 static classinfo *link_class_intern(classinfo *c)
439 classinfo *super; /* super class */
440 classinfo *tc; /* temporary class variable */
441 s4 supervftbllength; /* vftbllegnth of super class */
442 s4 vftbllength; /* vftbllength of current class */
443 s4 interfacetablelength; /* interface table length */
444 vftbl_t *v; /* vftbl of current class */
445 s4 i,j; /* interface/method/field counter */
446 arraydescriptor *arraydesc; /* descriptor for array classes */
447 #if defined(ENABLE_RT_TIMING)
448 struct timespec time_start, time_resolving, time_compute_vftbl,
449 time_abstract, time_compute_iftbl, time_fill_vftbl,
450 time_offsets, time_fill_iftbl, time_finalizer,
451 time_exceptions, time_subclasses;
454 RT_TIMING_GET_TIME(time_start);
456 /* the class is already linked */
458 if (c->state & CLASS_LINKED)
463 log_message_class("Linking class: ", c);
466 /* the class must be loaded */
468 /* XXX should this be a specific exception? */
469 assert(c->state & CLASS_LOADED);
471 /* cache the self-reference of this class */
472 /* we do this for cases where the defining loader of the class */
473 /* has not yet been recorded as an initiating loader for the class */
474 /* this is needed so subsequent code can assume that self-refs */
475 /* will always resolve lazily */
476 /* No need to do it for the bootloader - it is always registered */
477 /* as initiating loader for the classes it loads. */
479 classcache_store(c->classloader,c,false);
481 /* this class is currently linking */
483 c->state |= CLASS_LINKING;
487 /* check interfaces */
489 for (i = 0; i < c->interfacescount; i++) {
490 /* resolve this super interface */
492 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
496 c->interfaces[i].cls = tc;
498 /* detect circularity */
502 new_exception_utfmessage(string_java_lang_ClassCircularityError,
507 assert(tc->state & CLASS_LOADED);
509 if (!(tc->flags & ACC_INTERFACE)) {
511 new_exception_message(string_java_lang_IncompatibleClassChangeError,
512 "Implementing class");
516 if (!(tc->state & CLASS_LINKED))
521 /* check super class */
525 if (c->super.any == NULL) { /* class java.lang.Object */
527 c->instancesize = sizeof(java_objectheader);
529 vftbllength = supervftbllength = 0;
534 /* resolve super class */
536 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
539 c->super.cls = super;
541 /* detect circularity */
545 new_exception_utfmessage(string_java_lang_ClassCircularityError,
550 assert(super->state & CLASS_LOADED);
552 if (super->flags & ACC_INTERFACE) {
553 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
554 log_text("Interface specified as super class");
558 /* Don't allow extending final classes */
560 if (super->flags & ACC_FINAL) {
562 new_exception_message(string_java_lang_VerifyError,
563 "Cannot inherit from final class");
567 /* link the superclass if necessary */
569 if (!(super->state & CLASS_LINKED))
570 if (!link_class(super))
573 /* OR the ACC_CLASS_HAS_POINTERS flag */
575 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
577 /* handle array classes */
579 if (c->name->text[0] == '[')
580 if (!(arraydesc = link_array(c)))
583 if (c->flags & ACC_INTERFACE)
584 c->index = interfaceindex++;
586 c->index = super->index + 1;
588 c->instancesize = super->instancesize;
590 vftbllength = supervftbllength = super->vftbl->vftbllength;
592 c->finalizer = super->finalizer;
594 RT_TIMING_GET_TIME(time_resolving);
597 /* compute vftbl length */
599 for (i = 0; i < c->methodscount; i++) {
600 methodinfo *m = &(c->methods[i]);
602 if (!(m->flags & ACC_STATIC)) { /* is instance method */
608 for (j = 0; j < tc->methodscount; j++) {
609 if (method_canoverwrite(m, &(tc->methods[j]))) {
610 if (tc->methods[j].flags & ACC_PRIVATE)
611 goto notfoundvftblindex;
613 /* package-private methods in other packages */
614 /* must not be overridden */
615 /* (see Java Language Specification 8.4.8.1) */
616 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
617 && !SAME_PACKAGE(c,tc) )
619 goto notfoundvftblindex;
622 if (tc->methods[j].flags & ACC_FINAL) {
623 /* class a overrides final method . */
625 new_exception(string_java_lang_VerifyError);
629 /* method m overwrites method j of class tc */
631 #if defined(ENABLE_VERIFIER)
632 /* Add loading constraints (for the more general */
633 /* types of method tc->methods[j]). -- */
634 /* Not for <init>, as it is not invoked virtually. */
635 if ((m->name != utf_init)
636 && !classcache_add_constraints_for_params(
637 c->classloader, tc->classloader,
644 m->vftblindex = tc->methods[j].vftblindex;
645 goto foundvftblindex;
653 m->vftblindex = (vftbllength++);
658 RT_TIMING_GET_TIME(time_compute_vftbl);
661 /* Check all interfaces of an abstract class (maybe be an
662 interface too) for unimplemented methods. Such methods are
663 called miranda-methods and are marked with the ACC_MIRANDA
664 flag. VMClass.getDeclaredMethods does not return such
667 if (c->flags & ACC_ABSTRACT) {
670 s4 abstractmethodscount;
674 abstractmethodscount = 0;
676 /* check all interfaces of the abstract class */
678 for (i = 0; i < c->interfacescount; i++) {
679 ic = c->interfaces[i].cls;
681 for (j = 0; j < ic->methodscount; j++) {
682 im = &(ic->methods[j]);
684 /* skip `<clinit>' and `<init>' */
686 if ((im->name == utf_clinit) || (im->name == utf_init))
689 for (tc = c; tc != NULL; tc = tc->super.cls) {
690 for (k = 0; k < tc->methodscount; k++) {
691 if (method_canoverwrite(im, &(tc->methods[k])))
692 goto noabstractmethod;
696 abstractmethodscount++;
703 if (abstractmethodscount > 0) {
706 /* reallocate methods memory */
708 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
709 c->methodscount + abstractmethodscount);
711 for (i = 0; i < c->interfacescount; i++) {
712 ic = c->interfaces[i].cls;
714 for (j = 0; j < ic->methodscount; j++) {
715 im = &(ic->methods[j]);
717 /* skip `<clinit>' and `<init>' */
719 if ((im->name == utf_clinit) || (im->name == utf_init))
722 for (tc = c; tc != NULL; tc = tc->super.cls) {
723 for (k = 0; k < tc->methodscount; k++) {
724 if (method_canoverwrite(im, &(tc->methods[k])))
725 goto noabstractmethod2;
729 /* Copy the method found into the new c->methods
730 array and tag it as miranda-method. */
732 am = &(c->methods[c->methodscount]);
735 MCOPY(am, im, methodinfo, 1);
737 am->vftblindex = (vftbllength++);
739 am->flags |= ACC_MIRANDA;
747 RT_TIMING_GET_TIME(time_abstract);
750 #if defined(ENABLE_STATISTICS)
753 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
756 /* compute interfacetable length */
758 interfacetablelength = 0;
760 for (tc = c; tc != NULL; tc = tc->super.cls) {
761 for (i = 0; i < tc->interfacescount; i++) {
762 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
764 if (h > interfacetablelength)
765 interfacetablelength = h;
768 RT_TIMING_GET_TIME(time_compute_iftbl);
770 /* allocate virtual function table */
772 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
773 sizeof(methodptr) * (vftbllength - 1) +
774 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
775 v = (vftbl_t *) (((methodptr *) v) +
776 (interfacetablelength - 1) * (interfacetablelength > 1));
780 v->vftbllength = vftbllength;
781 v->interfacetablelength = interfacetablelength;
782 v->arraydesc = arraydesc;
784 /* store interface index in vftbl */
786 if (c->flags & ACC_INTERFACE)
787 v->baseval = -(c->index);
789 /* copy virtual function table of super class */
791 for (i = 0; i < supervftbllength; i++)
792 v->table[i] = super->vftbl->table[i];
794 /* Fill the remaining vftbl slots with the AbstractMethodError
795 stub (all after the super class slots, because they are already
798 for (; i < vftbllength; i++)
799 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
801 /* add method stubs into virtual function table */
803 for (i = 0; i < c->methodscount; i++) {
804 methodinfo *m = &(c->methods[i]);
806 assert(m->stubroutine == NULL);
808 /* Don't create a compiler stub for abstract methods as they
809 throw an AbstractMethodError with the default stub in the
810 vftbl. This entry is simply copied by sub-classes. */
812 if (m->flags & ACC_ABSTRACT)
815 #if defined(ENABLE_JIT)
816 # if defined(ENABLE_INTRP)
818 m->stubroutine = intrp_createcompilerstub(m);
821 m->stubroutine = createcompilerstub(m);
823 m->stubroutine = intrp_createcompilerstub(m);
826 /* static methods are not in the vftbl */
828 if (m->flags & ACC_STATIC)
831 /* insert the stubroutine into the vftbl */
833 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
835 RT_TIMING_GET_TIME(time_fill_vftbl);
837 /* compute instance size and offset of each field */
839 for (i = 0; i < c->fieldscount; i++) {
841 fieldinfo *f = &(c->fields[i]);
843 if (!(f->flags & ACC_STATIC)) {
844 dsize = descriptor_typesize(f->parseddesc);
846 /* On i386 we only align to 4 bytes even for double and s8. */
847 /* This matches what gcc does for struct members. We must */
848 /* do the same as gcc here because the offsets in native */
849 /* header structs like java_lang_Double must match the offsets */
850 /* of the Java fields (eg. java.lang.Double.value). */
851 #if defined(__I386__)
852 c->instancesize = ALIGN(c->instancesize, 4);
854 c->instancesize = ALIGN(c->instancesize, dsize);
857 f->offset = c->instancesize;
858 c->instancesize += dsize;
861 RT_TIMING_GET_TIME(time_offsets);
863 /* initialize interfacetable and interfacevftbllength */
865 v->interfacevftbllength = MNEW(s4, interfacetablelength);
867 #if defined(ENABLE_STATISTICS)
869 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
872 for (i = 0; i < interfacetablelength; i++) {
873 v->interfacevftbllength[i] = 0;
874 v->interfacetable[-i] = NULL;
879 for (tc = c; tc != NULL; tc = tc->super.cls)
880 for (i = 0; i < tc->interfacescount; i++)
881 if (!linker_addinterface(c, tc->interfaces[i].cls))
884 RT_TIMING_GET_TIME(time_fill_iftbl);
886 /* add finalizer method (not for java.lang.Object) */
891 fi = class_findmethod(c, utf_finalize, utf_void__void);
894 if (!(fi->flags & ACC_STATIC))
897 RT_TIMING_GET_TIME(time_finalizer);
899 /* resolve exception class references */
901 for (i = 0; i < c->methodscount; i++) {
902 methodinfo *m = &(c->methods[i]);
904 for (j = 0; j < m->exceptiontablelength; j++) {
905 if (!m->exceptiontable[j].catchtype.any)
907 if (!resolve_classref_or_classinfo(NULL,
908 m->exceptiontable[j].catchtype,
909 resolveEager, true, false,
910 &(m->exceptiontable[j].catchtype.cls)))
914 RT_TIMING_GET_TIME(time_exceptions);
918 linker_compute_subclasses(c);
920 RT_TIMING_GET_TIME(time_subclasses);
922 /* revert the linking state and class is linked */
924 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
928 log_message_class("Linking done class: ", c);
931 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
932 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
933 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
934 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
935 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
936 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
937 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
938 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
939 RT_TIMING_TIME_DIFF(time_finalizer ,time_exceptions ,RT_TIMING_LINK_EXCEPTS);
940 RT_TIMING_TIME_DIFF(time_exceptions ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
942 /* just return c to show that we didn't had a problem */
948 /* link_array ******************************************************************
950 This function is called by link_class to create the arraydescriptor
953 This function returns NULL if the array cannot be linked because
954 the component type has not been linked yet.
956 *******************************************************************************/
958 static arraydescriptor *link_array(classinfo *c)
962 arraydescriptor *desc;
967 namelen = c->name->blength;
969 /* Check the component type */
971 switch (c->name->text[1]) {
973 /* c is an array of arrays. */
974 u = utf_new(c->name->text + 1, namelen - 1);
975 if (!(comp = load_class_from_classloader(u, c->classloader)))
980 /* c is an array of objects. */
981 u = utf_new(c->name->text + 2, namelen - 3);
982 if (!(comp = load_class_from_classloader(u, c->classloader)))
987 /* If the component type has not been linked, link it now */
989 assert(!comp || (comp->state & CLASS_LOADED));
991 if (comp && !(comp->state & CLASS_LINKED))
992 if (!link_class(comp))
995 /* Allocate the arraydescriptor */
997 desc = NEW(arraydescriptor);
1000 /* c is an array of references */
1001 desc->arraytype = ARRAYTYPE_OBJECT;
1002 desc->componentsize = sizeof(void*);
1003 desc->dataoffset = OFFSET(java_objectarray, data);
1005 compvftbl = comp->vftbl;
1008 log_text("Component class has no vftbl");
1012 desc->componentvftbl = compvftbl;
1014 if (compvftbl->arraydesc) {
1015 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1017 if (compvftbl->arraydesc->dimension >= 255) {
1018 log_text("Creating array of dimension >255");
1022 desc->dimension = compvftbl->arraydesc->dimension + 1;
1023 desc->elementtype = compvftbl->arraydesc->elementtype;
1026 desc->elementvftbl = compvftbl;
1027 desc->dimension = 1;
1028 desc->elementtype = ARRAYTYPE_OBJECT;
1032 /* c is an array of a primitive type */
1033 switch (c->name->text[1]) {
1035 desc->arraytype = ARRAYTYPE_BOOLEAN;
1036 desc->dataoffset = OFFSET(java_booleanarray,data);
1037 desc->componentsize = sizeof(u1);
1041 desc->arraytype = ARRAYTYPE_BYTE;
1042 desc->dataoffset = OFFSET(java_bytearray,data);
1043 desc->componentsize = sizeof(u1);
1047 desc->arraytype = ARRAYTYPE_CHAR;
1048 desc->dataoffset = OFFSET(java_chararray,data);
1049 desc->componentsize = sizeof(u2);
1053 desc->arraytype = ARRAYTYPE_DOUBLE;
1054 desc->dataoffset = OFFSET(java_doublearray,data);
1055 desc->componentsize = sizeof(double);
1059 desc->arraytype = ARRAYTYPE_FLOAT;
1060 desc->dataoffset = OFFSET(java_floatarray,data);
1061 desc->componentsize = sizeof(float);
1065 desc->arraytype = ARRAYTYPE_INT;
1066 desc->dataoffset = OFFSET(java_intarray,data);
1067 desc->componentsize = sizeof(s4);
1071 desc->arraytype = ARRAYTYPE_LONG;
1072 desc->dataoffset = OFFSET(java_longarray,data);
1073 desc->componentsize = sizeof(s8);
1077 desc->arraytype = ARRAYTYPE_SHORT;
1078 desc->dataoffset = OFFSET(java_shortarray,data);
1079 desc->componentsize = sizeof(s2);
1083 *exceptionptr = new_noclassdeffounderror(c->name);
1087 desc->componentvftbl = NULL;
1088 desc->elementvftbl = NULL;
1089 desc->dimension = 1;
1090 desc->elementtype = desc->arraytype;
1097 /* linker_compute_subclasses ***************************************************
1101 *******************************************************************************/
1103 static void linker_compute_subclasses(classinfo *c)
1105 #if defined(ENABLE_THREADS)
1109 if (!(c->flags & ACC_INTERFACE)) {
1114 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1115 c->nextsub = c->super.cls->sub;
1116 c->super.cls->sub = c;
1121 /* compute class values */
1123 linker_compute_class_values(class_java_lang_Object);
1125 #if defined(ENABLE_THREADS)
1131 /* linker_compute_class_values *************************************************
1135 *******************************************************************************/
1137 static void linker_compute_class_values(classinfo *c)
1141 c->vftbl->baseval = ++classvalue;
1146 linker_compute_class_values(subs);
1148 subs = subs->nextsub;
1151 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1155 /* linker_addinterface *********************************************************
1157 Is needed by link_class for adding a VTBL to a class. All
1158 interfaces implemented by ic are added as well.
1161 true.........everything ok
1162 false........an exception has been thrown
1164 *******************************************************************************/
1166 static bool linker_addinterface(classinfo *c, classinfo *ic)
1177 if (i >= v->interfacetablelength)
1178 vm_abort("Internal error: interfacetable overflow");
1180 /* if this interface has already been added, return immediately */
1182 if (v->interfacetable[-i] != NULL)
1185 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1186 v->interfacevftbllength[i] = 1;
1187 v->interfacetable[-i] = MNEW(methodptr, 1);
1188 v->interfacetable[-i][0] = NULL;
1191 v->interfacevftbllength[i] = ic->methodscount;
1192 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1194 #if defined(ENABLE_STATISTICS)
1196 count_vftbl_len += sizeof(methodptr) *
1197 (ic->methodscount + (ic->methodscount == 0));
1200 for (j = 0; j < ic->methodscount; j++) {
1201 for (sc = c; sc != NULL; sc = sc->super.cls) {
1202 for (k = 0; k < sc->methodscount; k++) {
1203 m = &(sc->methods[k]);
1205 if (method_canoverwrite(m, &(ic->methods[j]))) {
1206 /* method m overwrites the (abstract) method */
1207 #if defined(ENABLE_VERIFIER)
1208 /* Add loading constraints (for the more
1209 general types of the method
1211 if (!classcache_add_constraints_for_params(
1212 c->classloader, ic->classloader,
1219 /* XXX taken from gcj */
1220 /* check for ACC_STATIC: IncompatibleClassChangeError */
1222 /* check for !ACC_PUBLIC: IllegalAccessError */
1224 /* check for ACC_ABSTRACT: AbstracMethodError,
1225 not sure about that one */
1227 v->interfacetable[-i][j] = v->table[m->vftblindex];
1233 /* If no method was found, insert the AbstractMethodError
1236 v->interfacetable[-i][j] =
1237 (methodptr) (ptrint) &asm_abstractmethoderror;
1244 /* add superinterfaces of this interface */
1246 for (j = 0; j < ic->interfacescount; j++)
1247 if (!linker_addinterface(c, ic->interfaces[j].cls))
1256 /* class_highestinterface ******************************************************
1258 Used by the function link_class to determine the amount of memory
1259 needed for the interface table.
1261 *******************************************************************************/
1263 static s4 class_highestinterface(classinfo *c)
1269 /* check for ACC_INTERFACE bit already done in link_class_intern */
1273 for (i = 0; i < c->interfacescount; i++) {
1274 h2 = class_highestinterface(c->interfaces[i].cls);
1285 * These are local overrides for various environment variables in Emacs.
1286 * Please do not remove this and leave it at the end of the file, where
1287 * Emacs will automagically detect them.
1288 * ---------------------------------------------------------------------
1291 * indent-tabs-mode: t
1295 * vim:noexpandtab:sw=4:ts=4: