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 4834 2006-04-25 12:25:43Z 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"
61 /* global variables ***********************************************************/
63 static s4 interfaceindex; /* sequential numbering of interfaces */
67 /* primitivetype_table *********************************************************
69 Structure for primitive classes: contains the class for wrapping
70 the primitive type, the primitive class, the name of the class for
71 wrapping, the one character type signature and the name of the
74 CAUTION: Don't change the order of the types. This table is indexed
75 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
77 *******************************************************************************/
79 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
80 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
81 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
82 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
83 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
84 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
85 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
86 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
87 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
88 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
89 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
90 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
94 /* private functions **********************************************************/
96 static bool link_primitivetype_table(void);
97 static classinfo *link_class_intern(classinfo *c);
98 static arraydescriptor *link_array(classinfo *c);
99 static void linker_compute_class_values(classinfo *c);
100 static void linker_compute_subclasses(classinfo *c);
101 static bool linker_addinterface(classinfo *c, classinfo *ic);
102 static s4 class_highestinterface(classinfo *c);
105 /* linker_init *****************************************************************
107 Initializes the linker subsystem.
109 *******************************************************************************/
111 bool linker_init(void)
113 /* reset interface index */
117 /* link java.lang.Class as first class of the system, because we
118 need it's vftbl for all other classes so we can use a class as
121 if (!link_class(class_java_lang_Class))
124 /* now set the header.vftbl of all classes which were created
125 before java.lang.Class was linked */
127 class_postset_header_vftbl();
130 /* link important system classes */
132 if (!link_class(class_java_lang_Object))
135 if (!link_class(class_java_lang_String))
138 if (!link_class(class_java_lang_Cloneable))
141 if (!link_class(class_java_io_Serializable))
145 /* link classes for wrapping primitive types */
147 if (!link_class(class_java_lang_Void))
150 if (!link_class(class_java_lang_Boolean))
153 if (!link_class(class_java_lang_Byte))
156 if (!link_class(class_java_lang_Character))
159 if (!link_class(class_java_lang_Short))
162 if (!link_class(class_java_lang_Integer))
165 if (!link_class(class_java_lang_Long))
168 if (!link_class(class_java_lang_Float))
171 if (!link_class(class_java_lang_Double))
175 /* load some other important classes */
177 if (!link_class(class_java_lang_ClassLoader))
180 if (!link_class(class_java_lang_SecurityManager))
183 if (!link_class(class_java_lang_System))
186 if (!link_class(class_java_lang_Thread))
189 if (!link_class(class_java_lang_ThreadGroup))
192 if (!link_class(class_java_lang_VMThread))
196 /* some classes which may be used more often */
198 if (!link_class(class_java_lang_StackTraceElement))
201 if (!link_class(class_java_lang_reflect_Constructor))
204 if (!link_class(class_java_lang_reflect_Field))
207 if (!link_class(class_java_lang_reflect_Method))
210 if (!link_class(class_java_security_PrivilegedAction))
213 if (!link_class(class_java_util_Vector))
216 if (!link_class(arrayclass_java_lang_Object))
220 /* create pseudo classes used by the typechecker */
222 /* pseudo class for Arraystubs (extends java.lang.Object) */
224 pseudo_class_Arraystub =
225 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
226 pseudo_class_Arraystub->state |= CLASS_LOADED;
227 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
228 pseudo_class_Arraystub->interfacescount = 2;
229 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
230 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
231 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
233 if (!classcache_store_unique(pseudo_class_Arraystub)) {
234 log_text("could not cache pseudo_class_Arraystub");
238 if (!link_class(pseudo_class_Arraystub))
241 /* pseudo class representing the null type */
243 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
244 pseudo_class_Null->state |= CLASS_LOADED;
245 pseudo_class_Null->super.cls = class_java_lang_Object;
247 if (!classcache_store_unique(pseudo_class_Null)) {
248 log_text("could not cache pseudo_class_Null");
252 if (!link_class(pseudo_class_Null))
255 /* pseudo class representing new uninitialized objects */
257 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
258 pseudo_class_New->state |= CLASS_LOADED;
259 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
260 pseudo_class_New->super.cls = class_java_lang_Object;
262 if (!classcache_store_unique(pseudo_class_New)) {
263 log_text("could not cache pseudo_class_New");
267 /* create classes representing primitive types */
269 if (!link_primitivetype_table())
273 /* Correct vftbl-entries (retarded loading and linking of class */
274 /* java/lang/String). */
276 stringtable_update();
282 /* link_primitivetype_table ****************************************************
284 Create classes representing primitive types.
286 *******************************************************************************/
288 static bool link_primitivetype_table(void)
294 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
297 if (!primitivetype_table[i].name)
300 /* create primitive class */
302 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
304 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
306 /* prevent loader from loading primitive class */
308 c->state |= CLASS_LOADED;
310 /* INFO: don't put primitive classes into the classcache */
315 primitivetype_table[i].class_primitive = c;
317 /* create class for wrapping the primitive type */
319 u = utf_new_char(primitivetype_table[i].wrapname);
321 if (!(c = load_class_bootstrap(u)))
324 primitivetype_table[i].class_wrap = c;
326 /* create the primitive array class */
328 if (primitivetype_table[i].arrayname) {
329 u = utf_new_char(primitivetype_table[i].arrayname);
330 c = class_create_classinfo(u);
331 c = load_newly_created_array(c, NULL);
335 primitivetype_table[i].arrayclass = c;
337 assert(c->state & CLASS_LOADED);
339 if (!(c->state & CLASS_LINKED))
343 primitivetype_table[i].arrayvftbl = c->vftbl;
351 /* link_class ******************************************************************
353 Wrapper function for link_class_intern to ease monitor enter/exit
354 and exception handling.
356 *******************************************************************************/
358 classinfo *link_class(classinfo *c)
361 #if defined(ENABLE_RT_TIMING)
362 struct timespec time_start, time_end;
365 RT_TIMING_GET_TIME(time_start);
368 exceptions_throw_nullpointerexception();
372 #if defined(USE_THREADS)
373 /* enter a monitor on the class */
375 builtin_monitorenter((java_objectheader *) c);
378 /* maybe the class is already linked */
380 if (c->state & CLASS_LINKED) {
381 #if defined(USE_THREADS)
382 builtin_monitorexit((java_objectheader *) c);
388 #if defined(ENABLE_STATISTICS)
391 if (opt_getcompilingtime)
392 compilingtime_stop();
394 if (opt_getloadingtime)
398 /* call the internal function */
400 r = link_class_intern(c);
402 /* if return value is NULL, we had a problem and the class is not linked */
405 c->state &= ~CLASS_LINKING;
407 #if defined(ENABLE_STATISTICS)
410 if (opt_getloadingtime)
413 if (opt_getcompilingtime)
414 compilingtime_start();
417 #if defined(USE_THREADS)
418 /* leave the monitor */
420 builtin_monitorexit((java_objectheader *) c);
423 RT_TIMING_GET_TIME(time_end);
425 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
431 /* link_class_intern ***********************************************************
433 Tries to link a class. The function calculates the length in bytes
434 that an instance of this class requires as well as the VTBL for
435 methods and interface methods.
437 *******************************************************************************/
439 static classinfo *link_class_intern(classinfo *c)
441 classinfo *super; /* super class */
442 classinfo *tc; /* temporary class variable */
443 s4 supervftbllength; /* vftbllegnth of super class */
444 s4 vftbllength; /* vftbllength of current class */
445 s4 interfacetablelength; /* interface table length */
446 vftbl_t *v; /* vftbl of current class */
447 s4 i,j; /* interface/method/field counter */
448 arraydescriptor *arraydesc; /* descriptor for array classes */
449 #if defined(ENABLE_RT_TIMING)
450 struct timespec time_start, time_resolving, time_compute_vftbl,
451 time_abstract, time_compute_iftbl, time_fill_vftbl,
452 time_offsets, time_fill_iftbl, time_finalizer,
453 time_exceptions, time_subclasses;
456 RT_TIMING_GET_TIME(time_start);
458 /* the class is already linked */
460 if (c->state & CLASS_LINKED)
465 log_message_class("Linking class: ", c);
468 /* the class must be loaded */
470 /* XXX should this be a specific exception? */
471 assert(c->state & CLASS_LOADED);
473 /* cache the self-reference of this class */
474 /* we do this for cases where the defining loader of the class */
475 /* has not yet been recorded as an initiating loader for the class */
476 /* this is needed so subsequent code can assume that self-refs */
477 /* will always resolve lazily */
478 /* No need to do it for the bootloader - it is always registered */
479 /* as initiating loader for the classes it loads. */
481 classcache_store(c->classloader,c,false);
483 /* this class is currently linking */
485 c->state |= CLASS_LINKING;
489 /* check interfaces */
491 for (i = 0; i < c->interfacescount; i++) {
492 /* resolve this super interface */
494 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
498 c->interfaces[i].cls = tc;
500 /* detect circularity */
504 new_exception_utfmessage(string_java_lang_ClassCircularityError,
509 assert(tc->state & CLASS_LOADED);
511 if (!(tc->flags & ACC_INTERFACE)) {
513 new_exception_message(string_java_lang_IncompatibleClassChangeError,
514 "Implementing class");
518 if (!(tc->state & CLASS_LINKED))
523 /* check super class */
527 if (c->super.any == NULL) { /* class java.lang.Object */
529 c->instancesize = sizeof(java_objectheader);
531 vftbllength = supervftbllength = 0;
536 /* resolve super class */
538 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
541 c->super.cls = super;
543 /* detect circularity */
547 new_exception_utfmessage(string_java_lang_ClassCircularityError,
552 assert(super->state & CLASS_LOADED);
554 if (super->flags & ACC_INTERFACE) {
555 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
556 log_text("Interface specified as super class");
560 /* Don't allow extending final classes */
562 if (super->flags & ACC_FINAL) {
564 new_exception_message(string_java_lang_VerifyError,
565 "Cannot inherit from final class");
569 /* link the superclass if necessary */
571 if (!(super->state & CLASS_LINKED))
572 if (!link_class(super))
575 /* OR the ACC_CLASS_HAS_POINTERS flag */
577 c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
579 /* handle array classes */
581 if (c->name->text[0] == '[')
582 if (!(arraydesc = link_array(c)))
585 if (c->flags & ACC_INTERFACE)
586 c->index = interfaceindex++;
588 c->index = super->index + 1;
590 c->instancesize = super->instancesize;
592 vftbllength = supervftbllength = super->vftbl->vftbllength;
594 c->finalizer = super->finalizer;
596 RT_TIMING_GET_TIME(time_resolving);
599 /* compute vftbl length */
601 for (i = 0; i < c->methodscount; i++) {
602 methodinfo *m = &(c->methods[i]);
604 if (!(m->flags & ACC_STATIC)) { /* is instance method */
610 for (j = 0; j < tc->methodscount; j++) {
611 if (method_canoverwrite(m, &(tc->methods[j]))) {
612 if (tc->methods[j].flags & ACC_PRIVATE)
613 goto notfoundvftblindex;
615 /* package-private methods in other packages */
616 /* must not be overridden */
617 /* (see Java Language Specification 8.4.8.1) */
618 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
619 && !SAME_PACKAGE(c,tc) )
621 goto notfoundvftblindex;
624 if (tc->methods[j].flags & ACC_FINAL) {
625 /* class a overrides final method . */
627 new_exception(string_java_lang_VerifyError);
631 /* method m overwrites method j of class tc */
633 #if defined(ENABLE_VERIFIER)
634 /* Add loading constraints (for the more general */
635 /* types of method tc->methods[j]). -- */
636 /* Not for <init>, as it is not invoked virtually. */
637 if ((m->name != utf_init)
638 && !classcache_add_constraints_for_params(
639 c->classloader, tc->classloader,
646 m->vftblindex = tc->methods[j].vftblindex;
647 goto foundvftblindex;
655 m->vftblindex = (vftbllength++);
660 RT_TIMING_GET_TIME(time_compute_vftbl);
663 /* Check all interfaces of an abtract class (maybe be an interface
664 too) for unimplemented methods. Such methods are called
665 miranda-methods and are marked with the ACC_MIRANDA flag.
666 VMClass.getDeclaredMethods does not return such methods. */
668 if (c->flags & ACC_ABSTRACT) {
671 s4 abstractmethodscount;
675 abstractmethodscount = 0;
677 /* check all interfaces of the abtract class */
679 for (i = 0; i < c->interfacescount; i++) {
680 ic = c->interfaces[i].cls;
682 for (j = 0; j < ic->methodscount; j++) {
683 im = &(ic->methods[j]);
685 /* skip `<clinit>' and `<init>' */
687 if ((im->name == utf_clinit) || (im->name == utf_init))
690 for (tc = c; tc != NULL; tc = tc->super.cls) {
691 for (k = 0; k < tc->methodscount; k++) {
692 if (method_canoverwrite(im, &(tc->methods[k])))
693 goto noabstractmethod;
697 abstractmethodscount++;
704 if (abstractmethodscount > 0) {
707 /* reallocate methods memory */
709 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
710 c->methodscount + abstractmethodscount);
712 for (i = 0; i < c->interfacescount; i++) {
713 ic = c->interfaces[i].cls;
715 for (j = 0; j < ic->methodscount; j++) {
716 im = &(ic->methods[j]);
718 /* skip `<clinit>' and `<init>' */
720 if ((im->name == utf_clinit) || (im->name == utf_init))
723 for (tc = c; tc != NULL; tc = tc->super.cls) {
724 for (k = 0; k < tc->methodscount; k++) {
725 if (method_canoverwrite(im, &(tc->methods[k])))
726 goto noabstractmethod2;
730 /* Copy the method found into the new c->methods
731 array and tag it as miranda-method. */
733 am = &(c->methods[c->methodscount]);
736 MCOPY(am, im, methodinfo, 1);
738 am->vftblindex = (vftbllength++);
740 am->flags |= ACC_MIRANDA;
748 RT_TIMING_GET_TIME(time_abstract);
751 #if defined(ENABLE_STATISTICS)
754 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
757 /* compute interfacetable length */
759 interfacetablelength = 0;
762 for (i = 0; i < tc->interfacescount; i++) {
763 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
764 if (h > interfacetablelength)
765 interfacetablelength = h;
769 RT_TIMING_GET_TIME(time_compute_iftbl);
771 /* allocate virtual function table */
773 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
774 sizeof(methodptr) * (vftbllength - 1) +
775 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
776 v = (vftbl_t *) (((methodptr *) v) +
777 (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 /* add method stubs into virtual function table */
796 for (i = 0; i < c->methodscount; i++) {
797 methodinfo *m = &(c->methods[i]);
799 /* Methods in ABSTRACT classes from interfaces maybe already
800 have a stubroutine. */
802 if (!m->stubroutine) {
803 #if defined(ENABLE_JIT)
804 # if defined(ENABLE_INTRP)
806 m->stubroutine = intrp_createcompilerstub(m);
809 m->stubroutine = createcompilerstub(m);
811 m->stubroutine = intrp_createcompilerstub(m);
815 if (!(m->flags & ACC_STATIC))
816 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
818 RT_TIMING_GET_TIME(time_fill_vftbl);
820 /* compute instance size and offset of each field */
822 for (i = 0; i < c->fieldscount; i++) {
824 fieldinfo *f = &(c->fields[i]);
826 if (!(f->flags & ACC_STATIC)) {
827 dsize = descriptor_typesize(f->parseddesc);
828 c->instancesize = ALIGN(c->instancesize, dsize);
829 f->offset = c->instancesize;
830 c->instancesize += dsize;
833 RT_TIMING_GET_TIME(time_offsets);
835 /* initialize interfacetable and interfacevftbllength */
837 v->interfacevftbllength = MNEW(s4, interfacetablelength);
839 #if defined(ENABLE_STATISTICS)
841 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
844 for (i = 0; i < interfacetablelength; i++) {
845 v->interfacevftbllength[i] = 0;
846 v->interfacetable[-i] = NULL;
851 for (tc = c; tc != NULL; tc = tc->super.cls)
852 for (i = 0; i < tc->interfacescount; i++)
853 if (!linker_addinterface(c, tc->interfaces[i].cls))
856 RT_TIMING_GET_TIME(time_fill_iftbl);
858 /* add finalizer method (not for java.lang.Object) */
863 fi = class_findmethod(c, utf_finalize, utf_void__void);
866 if (!(fi->flags & ACC_STATIC))
869 RT_TIMING_GET_TIME(time_finalizer);
871 /* resolve exception class references */
873 for (i = 0; i < c->methodscount; i++) {
874 methodinfo *m = &(c->methods[i]);
876 for (j = 0; j < m->exceptiontablelength; j++) {
877 if (!m->exceptiontable[j].catchtype.any)
879 if (!resolve_classref_or_classinfo(NULL,
880 m->exceptiontable[j].catchtype,
881 resolveEager, true, false,
882 &(m->exceptiontable[j].catchtype.cls)))
886 RT_TIMING_GET_TIME(time_exceptions);
890 linker_compute_subclasses(c);
892 RT_TIMING_GET_TIME(time_subclasses);
894 /* revert the linking state and class is linked */
896 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
900 log_message_class("Linking done class: ", c);
903 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
904 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
905 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
906 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
907 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
908 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
909 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
910 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
911 RT_TIMING_TIME_DIFF(time_finalizer ,time_exceptions ,RT_TIMING_LINK_EXCEPTS);
912 RT_TIMING_TIME_DIFF(time_exceptions ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
914 /* just return c to show that we didn't had a problem */
920 /* link_array ******************************************************************
922 This function is called by link_class to create the arraydescriptor
925 This function returns NULL if the array cannot be linked because
926 the component type has not been linked yet.
928 *******************************************************************************/
930 static arraydescriptor *link_array(classinfo *c)
934 arraydescriptor *desc;
939 namelen = c->name->blength;
941 /* Check the component type */
943 switch (c->name->text[1]) {
945 /* c is an array of arrays. */
946 u = utf_new(c->name->text + 1, namelen - 1);
947 if (!(comp = load_class_from_classloader(u, c->classloader)))
952 /* c is an array of objects. */
953 u = utf_new(c->name->text + 2, namelen - 3);
954 if (!(comp = load_class_from_classloader(u, c->classloader)))
959 /* If the component type has not been linked, link it now */
961 assert(!comp || (comp->state & CLASS_LOADED));
963 if (comp && !(comp->state & CLASS_LINKED))
964 if (!link_class(comp))
967 /* Allocate the arraydescriptor */
969 desc = NEW(arraydescriptor);
972 /* c is an array of references */
973 desc->arraytype = ARRAYTYPE_OBJECT;
974 desc->componentsize = sizeof(void*);
975 desc->dataoffset = OFFSET(java_objectarray, data);
977 compvftbl = comp->vftbl;
980 log_text("Component class has no vftbl");
984 desc->componentvftbl = compvftbl;
986 if (compvftbl->arraydesc) {
987 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
989 if (compvftbl->arraydesc->dimension >= 255) {
990 log_text("Creating array of dimension >255");
994 desc->dimension = compvftbl->arraydesc->dimension + 1;
995 desc->elementtype = compvftbl->arraydesc->elementtype;
998 desc->elementvftbl = compvftbl;
1000 desc->elementtype = ARRAYTYPE_OBJECT;
1004 /* c is an array of a primitive type */
1005 switch (c->name->text[1]) {
1007 desc->arraytype = ARRAYTYPE_BOOLEAN;
1008 desc->dataoffset = OFFSET(java_booleanarray,data);
1009 desc->componentsize = sizeof(u1);
1013 desc->arraytype = ARRAYTYPE_BYTE;
1014 desc->dataoffset = OFFSET(java_bytearray,data);
1015 desc->componentsize = sizeof(u1);
1019 desc->arraytype = ARRAYTYPE_CHAR;
1020 desc->dataoffset = OFFSET(java_chararray,data);
1021 desc->componentsize = sizeof(u2);
1025 desc->arraytype = ARRAYTYPE_DOUBLE;
1026 desc->dataoffset = OFFSET(java_doublearray,data);
1027 desc->componentsize = sizeof(double);
1031 desc->arraytype = ARRAYTYPE_FLOAT;
1032 desc->dataoffset = OFFSET(java_floatarray,data);
1033 desc->componentsize = sizeof(float);
1037 desc->arraytype = ARRAYTYPE_INT;
1038 desc->dataoffset = OFFSET(java_intarray,data);
1039 desc->componentsize = sizeof(s4);
1043 desc->arraytype = ARRAYTYPE_LONG;
1044 desc->dataoffset = OFFSET(java_longarray,data);
1045 desc->componentsize = sizeof(s8);
1049 desc->arraytype = ARRAYTYPE_SHORT;
1050 desc->dataoffset = OFFSET(java_shortarray,data);
1051 desc->componentsize = sizeof(s2);
1055 *exceptionptr = new_noclassdeffounderror(c->name);
1059 desc->componentvftbl = NULL;
1060 desc->elementvftbl = NULL;
1061 desc->dimension = 1;
1062 desc->elementtype = desc->arraytype;
1069 /* linker_compute_subclasses ***************************************************
1073 *******************************************************************************/
1075 static void linker_compute_subclasses(classinfo *c)
1077 #if defined(USE_THREADS)
1078 #if defined(NATIVE_THREADS)
1085 if (!(c->flags & ACC_INTERFACE)) {
1090 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1091 c->nextsub = c->super.cls->sub;
1092 c->super.cls->sub = c;
1097 /* compute class values */
1099 linker_compute_class_values(class_java_lang_Object);
1101 #if defined(USE_THREADS)
1102 #if defined(NATIVE_THREADS)
1111 /* linker_compute_class_values *************************************************
1115 *******************************************************************************/
1117 static void linker_compute_class_values(classinfo *c)
1121 c->vftbl->baseval = ++classvalue;
1126 linker_compute_class_values(subs);
1128 subs = subs->nextsub;
1131 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1135 /* linker_addinterface *********************************************************
1137 Is needed by link_class for adding a VTBL to a class. All
1138 interfaces implemented by ic are added as well.
1141 true.........everything ok
1142 false........an exception has been thrown
1144 *******************************************************************************/
1146 static bool linker_addinterface(classinfo *c, classinfo *ic)
1150 vftbl_t *v = c->vftbl;
1152 if (i >= v->interfacetablelength) {
1153 log_text("Inernal error: interfacetable overflow");
1157 /* if this interface has already been added, return immediately */
1159 if (v->interfacetable[-i])
1162 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1163 v->interfacevftbllength[i] = 1;
1164 v->interfacetable[-i] = MNEW(methodptr, 1);
1165 v->interfacetable[-i][0] = NULL;
1169 v->interfacevftbllength[i] = ic->methodscount;
1170 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1172 #if defined(ENABLE_STATISTICS)
1174 count_vftbl_len += sizeof(methodptr) *
1175 (ic->methodscount + (ic->methodscount == 0));
1178 for (j = 0; j < ic->methodscount; j++) {
1182 for (m = 0; m < sc->methodscount; m++) {
1183 methodinfo *mi = &(sc->methods[m]);
1185 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1186 /* method mi overwrites the (abstract) method */
1187 #if defined(ENABLE_VERIFIER)
1188 /* Add loading constraints (for the more general */
1189 /* types of the method ic->methods[j]). */
1190 if (!classcache_add_constraints_for_params(
1191 c->classloader, ic->classloader,
1197 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1208 /* add superinterfaces of this interface */
1210 for (j = 0; j < ic->interfacescount; j++)
1211 if (!linker_addinterface(c, ic->interfaces[j].cls))
1219 /* class_highestinterface ******************************************************
1221 Used by the function link_class to determine the amount of memory
1222 needed for the interface table.
1224 *******************************************************************************/
1226 static s4 class_highestinterface(classinfo *c)
1232 /* check for ACC_INTERFACE bit already done in link_class_intern */
1236 for (i = 0; i < c->interfacescount; i++) {
1237 h2 = class_highestinterface(c->interfaces[i].cls);
1248 * These are local overrides for various environment variables in Emacs.
1249 * Please do not remove this and leave it at the end of the file, where
1250 * Emacs will automagically detect them.
1251 * ---------------------------------------------------------------------
1254 * indent-tabs-mode: t
1258 * vim:noexpandtab:sw=4:ts=4: