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 5786 2006-10-15 22:44:56Z 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 /* 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_VMSystem))
203 if (!link_class(class_java_lang_VMThread))
207 /* some classes which may be used more often */
209 if (!link_class(class_java_lang_StackTraceElement))
212 if (!link_class(class_java_lang_reflect_Constructor))
215 if (!link_class(class_java_lang_reflect_Field))
218 if (!link_class(class_java_lang_reflect_Method))
221 if (!link_class(class_java_security_PrivilegedAction))
224 if (!link_class(class_java_util_Vector))
227 if (!link_class(arrayclass_java_lang_Object))
231 /* create pseudo classes used by the typechecker */
233 /* pseudo class for Arraystubs (extends java.lang.Object) */
235 pseudo_class_Arraystub =
236 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
237 pseudo_class_Arraystub->state |= CLASS_LOADED;
238 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
239 pseudo_class_Arraystub->interfacescount = 2;
240 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
241 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
242 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
244 if (!classcache_store_unique(pseudo_class_Arraystub)) {
245 log_text("could not cache pseudo_class_Arraystub");
249 if (!link_class(pseudo_class_Arraystub))
252 /* pseudo class representing the null type */
254 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
255 pseudo_class_Null->state |= CLASS_LOADED;
256 pseudo_class_Null->super.cls = class_java_lang_Object;
258 if (!classcache_store_unique(pseudo_class_Null)) {
259 log_text("could not cache pseudo_class_Null");
263 if (!link_class(pseudo_class_Null))
266 /* pseudo class representing new uninitialized objects */
268 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
269 pseudo_class_New->state |= CLASS_LOADED;
270 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
271 pseudo_class_New->super.cls = class_java_lang_Object;
273 if (!classcache_store_unique(pseudo_class_New)) {
274 log_text("could not cache pseudo_class_New");
278 /* create classes representing primitive types */
280 if (!link_primitivetype_table())
284 /* Correct vftbl-entries (retarded loading and linking of class */
285 /* java/lang/String). */
287 stringtable_update();
293 /* link_primitivetype_table ****************************************************
295 Create classes representing primitive types.
297 *******************************************************************************/
299 static bool link_primitivetype_table(void)
305 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
308 if (!primitivetype_table[i].name)
311 /* create primitive class */
313 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
315 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
317 /* prevent loader from loading primitive class */
319 c->state |= CLASS_LOADED;
321 /* INFO: don't put primitive classes into the classcache */
326 primitivetype_table[i].class_primitive = c;
328 /* create class for wrapping the primitive type */
330 u = utf_new_char(primitivetype_table[i].wrapname);
332 if (!(c = load_class_bootstrap(u)))
335 primitivetype_table[i].class_wrap = c;
337 /* create the primitive array class */
339 if (primitivetype_table[i].arrayname) {
340 u = utf_new_char(primitivetype_table[i].arrayname);
341 c = class_create_classinfo(u);
342 c = load_newly_created_array(c, NULL);
346 primitivetype_table[i].arrayclass = c;
348 assert(c->state & CLASS_LOADED);
350 if (!(c->state & CLASS_LINKED))
354 primitivetype_table[i].arrayvftbl = c->vftbl;
362 /* link_class ******************************************************************
364 Wrapper function for link_class_intern to ease monitor enter/exit
365 and exception handling.
367 *******************************************************************************/
369 classinfo *link_class(classinfo *c)
372 #if defined(ENABLE_RT_TIMING)
373 struct timespec time_start, time_end;
376 RT_TIMING_GET_TIME(time_start);
379 exceptions_throw_nullpointerexception();
383 LOCK_MONITOR_ENTER(c);
385 /* maybe the class is already linked */
387 if (c->state & CLASS_LINKED) {
388 LOCK_MONITOR_EXIT(c);
393 #if defined(ENABLE_STATISTICS)
396 if (opt_getcompilingtime)
397 compilingtime_stop();
399 if (opt_getloadingtime)
403 /* call the internal function */
405 r = link_class_intern(c);
407 /* if return value is NULL, we had a problem and the class is not linked */
410 c->state &= ~CLASS_LINKING;
412 #if defined(ENABLE_STATISTICS)
415 if (opt_getloadingtime)
418 if (opt_getcompilingtime)
419 compilingtime_start();
422 LOCK_MONITOR_EXIT(c);
424 RT_TIMING_GET_TIME(time_end);
426 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
432 /* link_class_intern ***********************************************************
434 Tries to link a class. The function calculates the length in bytes
435 that an instance of this class requires as well as the VTBL for
436 methods and interface methods.
438 *******************************************************************************/
440 static classinfo *link_class_intern(classinfo *c)
442 classinfo *super; /* super class */
443 classinfo *tc; /* temporary class variable */
444 s4 supervftbllength; /* vftbllegnth of super class */
445 s4 vftbllength; /* vftbllength of current class */
446 s4 interfacetablelength; /* interface table length */
447 vftbl_t *v; /* vftbl of current class */
448 s4 i; /* interface/method/field counter */
449 arraydescriptor *arraydesc; /* descriptor for array classes */
450 #if defined(ENABLE_RT_TIMING)
451 struct timespec time_start, time_resolving, time_compute_vftbl,
452 time_abstract, time_compute_iftbl, time_fill_vftbl,
453 time_offsets, time_fill_iftbl, time_finalizer,
457 RT_TIMING_GET_TIME(time_start);
459 /* the class is already linked */
461 if (c->state & CLASS_LINKED)
466 log_message_class("Linking class: ", c);
469 /* the class must be loaded */
471 /* XXX should this be a specific exception? */
472 assert(c->state & CLASS_LOADED);
474 /* cache the self-reference of this class */
475 /* we do this for cases where the defining loader of the class */
476 /* has not yet been recorded as an initiating loader for the class */
477 /* this is needed so subsequent code can assume that self-refs */
478 /* will always resolve lazily */
479 /* No need to do it for the bootloader - it is always registered */
480 /* as initiating loader for the classes it loads. */
482 classcache_store(c->classloader,c,false);
484 /* this class is currently linking */
486 c->state |= CLASS_LINKING;
490 /* check interfaces */
492 for (i = 0; i < c->interfacescount; i++) {
493 /* resolve this super interface */
495 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
499 c->interfaces[i].cls = tc;
501 /* detect circularity */
505 new_exception_utfmessage(string_java_lang_ClassCircularityError,
510 assert(tc->state & CLASS_LOADED);
512 if (!(tc->flags & ACC_INTERFACE)) {
514 new_exception_message(string_java_lang_IncompatibleClassChangeError,
515 "Implementing class");
519 if (!(tc->state & CLASS_LINKED))
524 /* check super class */
528 if (c->super.any == NULL) { /* class java.lang.Object */
530 c->instancesize = sizeof(java_objectheader);
532 vftbllength = supervftbllength = 0;
537 /* resolve super class */
539 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
542 c->super.cls = super;
544 /* detect circularity */
548 new_exception_utfmessage(string_java_lang_ClassCircularityError,
553 assert(super->state & CLASS_LOADED);
555 if (super->flags & ACC_INTERFACE) {
556 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
557 log_text("Interface specified as super class");
561 /* Don't allow extending final classes */
563 if (super->flags & ACC_FINAL) {
565 new_exception_message(string_java_lang_VerifyError,
566 "Cannot inherit from final class");
570 /* link the superclass if necessary */
572 if (!(super->state & CLASS_LINKED))
573 if (!link_class(super))
576 /* OR the ACC_CLASS_HAS_POINTERS flag */
578 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
580 /* handle array classes */
582 if (c->name->text[0] == '[')
583 if (!(arraydesc = link_array(c)))
586 if (c->flags & ACC_INTERFACE)
587 c->index = interfaceindex++;
589 c->index = super->index + 1;
591 c->instancesize = super->instancesize;
593 vftbllength = supervftbllength = super->vftbl->vftbllength;
595 c->finalizer = super->finalizer;
597 RT_TIMING_GET_TIME(time_resolving);
600 /* compute vftbl length */
602 for (i = 0; i < c->methodscount; i++) {
603 methodinfo *m = &(c->methods[i]);
605 if (!(m->flags & ACC_STATIC)) { /* is instance method */
611 for (j = 0; j < tc->methodscount; j++) {
612 if (method_canoverwrite(m, &(tc->methods[j]))) {
613 if (tc->methods[j].flags & ACC_PRIVATE)
614 goto notfoundvftblindex;
616 /* package-private methods in other packages */
617 /* must not be overridden */
618 /* (see Java Language Specification 8.4.8.1) */
619 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
620 && !SAME_PACKAGE(c,tc) )
622 goto notfoundvftblindex;
625 if (tc->methods[j].flags & ACC_FINAL) {
626 /* class a overrides final method . */
628 new_exception(string_java_lang_VerifyError);
632 /* method m overwrites method j of class tc */
634 #if defined(ENABLE_VERIFIER)
635 /* Add loading constraints (for the more general */
636 /* types of method tc->methods[j]). -- */
637 /* Not for <init>, as it is not invoked virtually. */
638 if ((m->name != utf_init)
639 && !classcache_add_constraints_for_params(
640 c->classloader, tc->classloader,
647 m->vftblindex = tc->methods[j].vftblindex;
648 goto foundvftblindex;
656 m->vftblindex = (vftbllength++);
661 RT_TIMING_GET_TIME(time_compute_vftbl);
664 /* Check all interfaces of an abstract class (maybe be an
665 interface too) for unimplemented methods. Such methods are
666 called miranda-methods and are marked with the ACC_MIRANDA
667 flag. VMClass.getDeclaredMethods does not return such
670 if (c->flags & ACC_ABSTRACT) {
673 s4 abstractmethodscount;
677 abstractmethodscount = 0;
679 /* check all interfaces of the abstract class */
681 for (i = 0; i < c->interfacescount; i++) {
682 ic = c->interfaces[i].cls;
684 for (j = 0; j < ic->methodscount; j++) {
685 im = &(ic->methods[j]);
687 /* skip `<clinit>' and `<init>' */
689 if ((im->name == utf_clinit) || (im->name == utf_init))
692 for (tc = c; tc != NULL; tc = tc->super.cls) {
693 for (k = 0; k < tc->methodscount; k++) {
694 if (method_canoverwrite(im, &(tc->methods[k])))
695 goto noabstractmethod;
699 abstractmethodscount++;
706 if (abstractmethodscount > 0) {
709 /* reallocate methods memory */
711 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
712 c->methodscount + abstractmethodscount);
714 for (i = 0; i < c->interfacescount; i++) {
715 ic = c->interfaces[i].cls;
717 for (j = 0; j < ic->methodscount; j++) {
718 im = &(ic->methods[j]);
720 /* skip `<clinit>' and `<init>' */
722 if ((im->name == utf_clinit) || (im->name == utf_init))
725 for (tc = c; tc != NULL; tc = tc->super.cls) {
726 for (k = 0; k < tc->methodscount; k++) {
727 if (method_canoverwrite(im, &(tc->methods[k])))
728 goto noabstractmethod2;
732 /* Copy the method found into the new c->methods
733 array and tag it as miranda-method. */
735 am = &(c->methods[c->methodscount]);
738 MCOPY(am, im, methodinfo, 1);
740 am->vftblindex = (vftbllength++);
742 am->flags |= ACC_MIRANDA;
750 RT_TIMING_GET_TIME(time_abstract);
753 #if defined(ENABLE_STATISTICS)
756 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
759 /* compute interfacetable length */
761 interfacetablelength = 0;
763 for (tc = c; tc != NULL; tc = tc->super.cls) {
764 for (i = 0; i < tc->interfacescount; i++) {
765 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
767 if (h > interfacetablelength)
768 interfacetablelength = h;
771 RT_TIMING_GET_TIME(time_compute_iftbl);
773 /* allocate virtual function table */
775 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
776 sizeof(methodptr) * (vftbllength - 1) +
777 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
778 v = (vftbl_t *) (((methodptr *) v) +
779 (interfacetablelength - 1) * (interfacetablelength > 1));
783 v->vftbllength = vftbllength;
784 v->interfacetablelength = interfacetablelength;
785 v->arraydesc = arraydesc;
787 /* store interface index in vftbl */
789 if (c->flags & ACC_INTERFACE)
790 v->baseval = -(c->index);
792 /* copy virtual function table of super class */
794 for (i = 0; i < supervftbllength; i++)
795 v->table[i] = super->vftbl->table[i];
797 /* Fill the remaining vftbl slots with the AbstractMethodError
798 stub (all after the super class slots, because they are already
801 for (; i < vftbllength; i++)
802 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
804 /* add method stubs into virtual function table */
806 for (i = 0; i < c->methodscount; i++) {
807 methodinfo *m = &(c->methods[i]);
809 assert(m->stubroutine == NULL);
811 /* Don't create a compiler stub for abstract methods as they
812 throw an AbstractMethodError with the default stub in the
813 vftbl. This entry is simply copied by sub-classes. */
815 if (m->flags & ACC_ABSTRACT)
818 #if defined(ENABLE_JIT)
819 # if defined(ENABLE_INTRP)
821 m->stubroutine = intrp_createcompilerstub(m);
824 m->stubroutine = createcompilerstub(m);
826 m->stubroutine = intrp_createcompilerstub(m);
829 /* static methods are not in the vftbl */
831 if (m->flags & ACC_STATIC)
834 /* insert the stubroutine into the vftbl */
836 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
838 RT_TIMING_GET_TIME(time_fill_vftbl);
840 /* compute instance size and offset of each field */
842 for (i = 0; i < c->fieldscount; i++) {
844 fieldinfo *f = &(c->fields[i]);
846 if (!(f->flags & ACC_STATIC)) {
847 dsize = descriptor_typesize(f->parseddesc);
849 /* On i386 we only align to 4 bytes even for double and s8. */
850 /* This matches what gcc does for struct members. We must */
851 /* do the same as gcc here because the offsets in native */
852 /* header structs like java_lang_Double must match the offsets */
853 /* of the Java fields (eg. java.lang.Double.value). */
854 #if defined(__I386__)
855 c->instancesize = ALIGN(c->instancesize, 4);
857 c->instancesize = ALIGN(c->instancesize, dsize);
860 f->offset = c->instancesize;
861 c->instancesize += dsize;
864 RT_TIMING_GET_TIME(time_offsets);
866 /* initialize interfacetable and interfacevftbllength */
868 v->interfacevftbllength = MNEW(s4, interfacetablelength);
870 #if defined(ENABLE_STATISTICS)
872 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
875 for (i = 0; i < interfacetablelength; i++) {
876 v->interfacevftbllength[i] = 0;
877 v->interfacetable[-i] = NULL;
882 for (tc = c; tc != NULL; tc = tc->super.cls)
883 for (i = 0; i < tc->interfacescount; i++)
884 if (!linker_addinterface(c, tc->interfaces[i].cls))
887 RT_TIMING_GET_TIME(time_fill_iftbl);
889 /* add finalizer method (not for java.lang.Object) */
894 fi = class_findmethod(c, utf_finalize, utf_void__void);
897 if (!(fi->flags & ACC_STATIC))
900 RT_TIMING_GET_TIME(time_finalizer);
904 linker_compute_subclasses(c);
906 RT_TIMING_GET_TIME(time_subclasses);
908 /* revert the linking state and class is linked */
910 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
914 log_message_class("Linking done class: ", c);
917 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
918 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
919 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
920 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
921 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
922 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
923 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
924 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
925 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
927 /* just return c to show that we didn't had a problem */
933 /* link_array ******************************************************************
935 This function is called by link_class to create the arraydescriptor
938 This function returns NULL if the array cannot be linked because
939 the component type has not been linked yet.
941 *******************************************************************************/
943 static arraydescriptor *link_array(classinfo *c)
947 arraydescriptor *desc;
952 namelen = c->name->blength;
954 /* Check the component type */
956 switch (c->name->text[1]) {
958 /* c is an array of arrays. */
959 u = utf_new(c->name->text + 1, namelen - 1);
960 if (!(comp = load_class_from_classloader(u, c->classloader)))
965 /* c is an array of objects. */
966 u = utf_new(c->name->text + 2, namelen - 3);
967 if (!(comp = load_class_from_classloader(u, c->classloader)))
972 /* If the component type has not been linked, link it now */
974 assert(!comp || (comp->state & CLASS_LOADED));
976 if (comp && !(comp->state & CLASS_LINKED))
977 if (!link_class(comp))
980 /* Allocate the arraydescriptor */
982 desc = NEW(arraydescriptor);
985 /* c is an array of references */
986 desc->arraytype = ARRAYTYPE_OBJECT;
987 desc->componentsize = sizeof(void*);
988 desc->dataoffset = OFFSET(java_objectarray, data);
990 compvftbl = comp->vftbl;
993 log_text("Component class has no vftbl");
997 desc->componentvftbl = compvftbl;
999 if (compvftbl->arraydesc) {
1000 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1002 if (compvftbl->arraydesc->dimension >= 255) {
1003 log_text("Creating array of dimension >255");
1007 desc->dimension = compvftbl->arraydesc->dimension + 1;
1008 desc->elementtype = compvftbl->arraydesc->elementtype;
1011 desc->elementvftbl = compvftbl;
1012 desc->dimension = 1;
1013 desc->elementtype = ARRAYTYPE_OBJECT;
1017 /* c is an array of a primitive type */
1018 switch (c->name->text[1]) {
1020 desc->arraytype = ARRAYTYPE_BOOLEAN;
1021 desc->dataoffset = OFFSET(java_booleanarray,data);
1022 desc->componentsize = sizeof(u1);
1026 desc->arraytype = ARRAYTYPE_BYTE;
1027 desc->dataoffset = OFFSET(java_bytearray,data);
1028 desc->componentsize = sizeof(u1);
1032 desc->arraytype = ARRAYTYPE_CHAR;
1033 desc->dataoffset = OFFSET(java_chararray,data);
1034 desc->componentsize = sizeof(u2);
1038 desc->arraytype = ARRAYTYPE_DOUBLE;
1039 desc->dataoffset = OFFSET(java_doublearray,data);
1040 desc->componentsize = sizeof(double);
1044 desc->arraytype = ARRAYTYPE_FLOAT;
1045 desc->dataoffset = OFFSET(java_floatarray,data);
1046 desc->componentsize = sizeof(float);
1050 desc->arraytype = ARRAYTYPE_INT;
1051 desc->dataoffset = OFFSET(java_intarray,data);
1052 desc->componentsize = sizeof(s4);
1056 desc->arraytype = ARRAYTYPE_LONG;
1057 desc->dataoffset = OFFSET(java_longarray,data);
1058 desc->componentsize = sizeof(s8);
1062 desc->arraytype = ARRAYTYPE_SHORT;
1063 desc->dataoffset = OFFSET(java_shortarray,data);
1064 desc->componentsize = sizeof(s2);
1068 *exceptionptr = new_noclassdeffounderror(c->name);
1072 desc->componentvftbl = NULL;
1073 desc->elementvftbl = NULL;
1074 desc->dimension = 1;
1075 desc->elementtype = desc->arraytype;
1082 /* linker_compute_subclasses ***************************************************
1086 *******************************************************************************/
1088 static void linker_compute_subclasses(classinfo *c)
1090 #if defined(ENABLE_THREADS)
1094 if (!(c->flags & ACC_INTERFACE)) {
1099 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1100 c->nextsub = c->super.cls->sub;
1101 c->super.cls->sub = c;
1106 /* compute class values */
1108 linker_compute_class_values(class_java_lang_Object);
1110 #if defined(ENABLE_THREADS)
1116 /* linker_compute_class_values *************************************************
1120 *******************************************************************************/
1122 static void linker_compute_class_values(classinfo *c)
1126 c->vftbl->baseval = ++classvalue;
1131 linker_compute_class_values(subs);
1133 subs = subs->nextsub;
1136 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1140 /* linker_addinterface *********************************************************
1142 Is needed by link_class for adding a VTBL to a class. All
1143 interfaces implemented by ic are added as well.
1146 true.........everything ok
1147 false........an exception has been thrown
1149 *******************************************************************************/
1151 static bool linker_addinterface(classinfo *c, classinfo *ic)
1162 if (i >= v->interfacetablelength)
1163 vm_abort("Internal error: interfacetable overflow");
1165 /* if this interface has already been added, return immediately */
1167 if (v->interfacetable[-i] != NULL)
1170 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1171 v->interfacevftbllength[i] = 1;
1172 v->interfacetable[-i] = MNEW(methodptr, 1);
1173 v->interfacetable[-i][0] = NULL;
1176 v->interfacevftbllength[i] = ic->methodscount;
1177 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1179 #if defined(ENABLE_STATISTICS)
1181 count_vftbl_len += sizeof(methodptr) *
1182 (ic->methodscount + (ic->methodscount == 0));
1185 for (j = 0; j < ic->methodscount; j++) {
1186 for (sc = c; sc != NULL; sc = sc->super.cls) {
1187 for (k = 0; k < sc->methodscount; k++) {
1188 m = &(sc->methods[k]);
1190 if (method_canoverwrite(m, &(ic->methods[j]))) {
1191 /* method m overwrites the (abstract) method */
1192 #if defined(ENABLE_VERIFIER)
1193 /* Add loading constraints (for the more
1194 general types of the method
1196 if (!classcache_add_constraints_for_params(
1197 c->classloader, ic->classloader,
1204 /* XXX taken from gcj */
1205 /* check for ACC_STATIC: IncompatibleClassChangeError */
1207 /* check for !ACC_PUBLIC: IllegalAccessError */
1209 /* check for ACC_ABSTRACT: AbstracMethodError,
1210 not sure about that one */
1212 v->interfacetable[-i][j] = v->table[m->vftblindex];
1218 /* If no method was found, insert the AbstractMethodError
1221 v->interfacetable[-i][j] =
1222 (methodptr) (ptrint) &asm_abstractmethoderror;
1229 /* add superinterfaces of this interface */
1231 for (j = 0; j < ic->interfacescount; j++)
1232 if (!linker_addinterface(c, ic->interfaces[j].cls))
1241 /* class_highestinterface ******************************************************
1243 Used by the function link_class to determine the amount of memory
1244 needed for the interface table.
1246 *******************************************************************************/
1248 static s4 class_highestinterface(classinfo *c)
1254 /* check for ACC_INTERFACE bit already done in link_class_intern */
1258 for (i = 0; i < c->interfacescount; i++) {
1259 h2 = class_highestinterface(c->interfaces[i].cls);
1270 * These are local overrides for various environment variables in Emacs.
1271 * Please do not remove this and leave it at the end of the file, where
1272 * Emacs will automagically detect them.
1273 * ---------------------------------------------------------------------
1276 * indent-tabs-mode: t
1280 * vim:noexpandtab:sw=4:ts=4: