1 /* src/vmcore/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: linker.c 8330 2007-08-16 18:15:51Z twisti $
36 #include "mm/memory.h"
38 #include "native/native.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/logging.h"
44 #include "vm/access.h"
46 #include "vm/exceptions.h"
47 #include "vm/primitive.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit_interface.h"
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/loader.h"
56 #include "vmcore/options.h"
57 #include "vmcore/rt-timing.h"
59 /* #include "vm/resolve.h" */
60 /* copied prototype to avoid bootstrapping problem: */
61 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
63 #if defined(ENABLE_STATISTICS)
64 # include "vmcore/statistics.h"
67 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
68 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
70 #define INLINELOG(code)
74 /* global variables ***********************************************************/
76 static s4 interfaceindex; /* sequential numbering of interfaces */
79 java_object_t *linker_classrenumber_lock;
82 /* private functions **********************************************************/
84 static classinfo *link_class_intern(classinfo *c);
85 static arraydescriptor *link_array(classinfo *c);
86 static void linker_compute_class_values(classinfo *c);
87 static void linker_compute_subclasses(classinfo *c);
88 static bool linker_addinterface(classinfo *c, classinfo *ic);
89 static s4 class_highestinterface(classinfo *c);
92 /* dummy structures for alinment checks ***************************************/
94 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
95 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
97 struct dummy_alignment_long_t {
102 struct dummy_alignment_double_t {
108 /* linker_init *****************************************************************
110 Initializes the linker subsystem.
112 *******************************************************************************/
114 bool linker_init(void)
116 /* Check for if alignment for long and double matches what we
117 assume for the current architecture. */
119 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
120 if (OFFSET(dummy_alignment_long_t, l) != 4)
121 vm_abort("linker_init: long alignment is different from what assumed: %d != %d",
122 OFFSET(dummy_alignment_long_t, l), 4);
124 if (OFFSET(dummy_alignment_double_t, d) != 4)
125 vm_abort("linker_init: double alignment is different from what assumed: %d != %d",
126 OFFSET(dummy_alignment_double_t, d), 4);
128 if (OFFSET(dummy_alignment_long_t, l) != 8)
129 vm_abort("linker_init: long alignment is different from what assumed: %d != %d",
130 OFFSET(dummy_alignment_long_t, l), 8);
132 if (OFFSET(dummy_alignment_double_t, d) != 8)
133 vm_abort("linker_init: double alignment is different from what assumed: %d != %d",
134 OFFSET(dummy_alignment_double_t, d), 8);
137 /* reset interface index */
141 #if defined(ENABLE_THREADS)
142 /* create the global lock object */
144 linker_classrenumber_lock = NEW(java_object_t);
146 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
149 /* link java.lang.Class as first class of the system, because we
150 need it's vftbl for all other classes so we can use a class as
153 if (!link_class(class_java_lang_Class))
156 /* now set the header.vftbl of all classes which were created
157 before java.lang.Class was linked */
159 class_postset_header_vftbl();
162 /* link important system classes */
164 if (!link_class(class_java_lang_Object))
167 if (!link_class(class_java_lang_String))
170 #if defined(ENABLE_JAVASE)
171 if (!link_class(class_java_lang_Cloneable))
174 if (!link_class(class_java_io_Serializable))
178 /* link classes for wrapping primitive types */
180 #if defined(ENABLE_JAVASE)
181 if (!link_class(class_java_lang_Void))
185 if (!link_class(class_java_lang_Boolean))
188 if (!link_class(class_java_lang_Byte))
191 if (!link_class(class_java_lang_Character))
194 if (!link_class(class_java_lang_Short))
197 if (!link_class(class_java_lang_Integer))
200 if (!link_class(class_java_lang_Long))
203 if (!link_class(class_java_lang_Float))
206 if (!link_class(class_java_lang_Double))
210 /* load some other important classes */
212 #if defined(ENABLE_JAVASE)
213 if (!link_class(class_java_lang_ClassLoader))
216 if (!link_class(class_java_lang_SecurityManager))
220 if (!link_class(class_java_lang_System))
223 if (!link_class(class_java_lang_Thread))
226 #if defined(ENABLE_JAVASE)
227 if (!link_class(class_java_lang_ThreadGroup))
231 #if defined(WITH_CLASSPATH_GNU)
232 if (!link_class(class_java_lang_VMSystem))
235 if (!link_class(class_java_lang_VMThread))
240 /* some classes which may be used more often */
242 #if defined(ENABLE_JAVASE)
243 if (!link_class(class_java_lang_StackTraceElement))
246 if (!link_class(class_java_lang_reflect_Constructor))
249 if (!link_class(class_java_lang_reflect_Field))
252 if (!link_class(class_java_lang_reflect_Method))
255 if (!link_class(class_java_security_PrivilegedAction))
258 if (!link_class(class_java_util_Vector))
261 # if defined(WITH_CLASSPATH_SUN)
262 if (!link_class(class_sun_reflect_MagicAccessorImpl))
266 if (!link_class(arrayclass_java_lang_Object))
271 /* create pseudo classes used by the typechecker */
273 /* pseudo class for Arraystubs (extends java.lang.Object) */
275 pseudo_class_Arraystub =
276 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
277 pseudo_class_Arraystub->state |= CLASS_LOADED;
278 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
280 #if defined(ENABLE_JAVASE)
281 pseudo_class_Arraystub->interfacescount = 2;
282 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
283 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
284 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
285 #elif defined(ENABLE_JAVAME_CLDC1_1)
286 pseudo_class_Arraystub->interfacescount = 0;
287 pseudo_class_Arraystub->interfaces = NULL;
290 if (!classcache_store_unique(pseudo_class_Arraystub)) {
291 log_text("could not cache pseudo_class_Arraystub");
295 if (!link_class(pseudo_class_Arraystub))
298 /* pseudo class representing the null type */
300 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
301 pseudo_class_Null->state |= CLASS_LOADED;
302 pseudo_class_Null->super.cls = class_java_lang_Object;
304 if (!classcache_store_unique(pseudo_class_Null))
305 vm_abort("linker_init: could not cache pseudo_class_Null");
307 if (!link_class(pseudo_class_Null))
310 /* pseudo class representing new uninitialized objects */
312 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
313 pseudo_class_New->state |= CLASS_LOADED;
314 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
315 pseudo_class_New->super.cls = class_java_lang_Object;
317 if (!classcache_store_unique(pseudo_class_New))
318 vm_abort("linker_init: could not cache pseudo_class_New");
320 /* Correct vftbl-entries (retarded loading and linking of class
321 java/lang/String). */
323 stringtable_update();
329 /* link_class ******************************************************************
331 Wrapper function for link_class_intern to ease monitor enter/exit
332 and exception handling.
334 *******************************************************************************/
336 classinfo *link_class(classinfo *c)
339 #if defined(ENABLE_RT_TIMING)
340 struct timespec time_start, time_end;
343 RT_TIMING_GET_TIME(time_start);
346 exceptions_throw_nullpointerexception();
350 LOCK_MONITOR_ENTER(c);
352 /* maybe the class is already linked */
354 if (c->state & CLASS_LINKED) {
355 LOCK_MONITOR_EXIT(c);
360 #if defined(ENABLE_STATISTICS)
363 if (opt_getcompilingtime)
364 compilingtime_stop();
366 if (opt_getloadingtime)
370 /* call the internal function */
372 r = link_class_intern(c);
374 /* if return value is NULL, we had a problem and the class is not linked */
377 c->state &= ~CLASS_LINKING;
379 #if defined(ENABLE_STATISTICS)
382 if (opt_getloadingtime)
385 if (opt_getcompilingtime)
386 compilingtime_start();
389 LOCK_MONITOR_EXIT(c);
391 RT_TIMING_GET_TIME(time_end);
393 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
399 /* linker_overwrite_method *****************************************************
401 Overwrite a method with another one, update method flags and check
405 mg................the general method being overwritten
406 ms................the overwriting (more specialized) method
407 wl................worklist where to add invalidated methods
410 true..............everything ok
411 false.............an exception has been thrown
413 *******************************************************************************/
415 static bool linker_overwrite_method(methodinfo *mg,
417 method_worklist **wl)
425 /* overriding a final method is illegal */
427 if (mg->flags & ACC_FINAL) {
428 exceptions_throw_verifyerror(mg, "Overriding final method");
432 /* method ms overwrites method mg */
434 #if defined(ENABLE_VERIFIER)
435 /* Add loading constraints (for the more general types of method mg). */
436 /* Not for <init>, as it is not invoked virtually. */
438 if ((ms->name != utf_init)
439 && !classcache_add_constraints_for_params(
440 cs->classloader, cg->classloader, mg))
446 /* inherit the vftbl index, and record the overwriting */
448 ms->vftblindex = mg->vftblindex;
451 /* update flags and check assumptions */
452 /* <init> methods are a special case, as they are never dispatched dynamically */
454 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
456 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
457 /* this adds another implementation */
459 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
461 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
463 method_break_assumption_monomorphic(mg, wl);
466 /* this is the first implementation */
468 mg->flags |= ACC_METHOD_IMPLEMENTED;
470 INLINELOG( printf("becomes implemented: "); method_println(mg); );
475 } while (mg != NULL);
482 /* link_class_intern ***********************************************************
484 Tries to link a class. The function calculates the length in bytes
485 that an instance of this class requires as well as the VTBL for
486 methods and interface methods.
488 *******************************************************************************/
490 static classinfo *link_class_intern(classinfo *c)
492 classinfo *super; /* super class */
493 classinfo *tc; /* temporary class variable */
494 s4 supervftbllength; /* vftbllegnth of super class */
495 s4 vftbllength; /* vftbllength of current class */
496 s4 interfacetablelength; /* interface table length */
497 vftbl_t *v; /* vftbl of current class */
498 s4 i; /* interface/method/field counter */
499 arraydescriptor *arraydesc; /* descriptor for array classes */
500 method_worklist *worklist; /* worklist for recompilation */
501 #if defined(ENABLE_RT_TIMING)
502 struct timespec time_start, time_resolving, time_compute_vftbl,
503 time_abstract, time_compute_iftbl, time_fill_vftbl,
504 time_offsets, time_fill_iftbl, time_finalizer,
508 RT_TIMING_GET_TIME(time_start);
510 /* the class is already linked */
512 if (c->state & CLASS_LINKED)
517 log_message_class("Linking class: ", c);
520 /* the class must be loaded */
522 /* XXX should this be a specific exception? */
523 assert(c->state & CLASS_LOADED);
525 /* cache the self-reference of this class */
526 /* we do this for cases where the defining loader of the class */
527 /* has not yet been recorded as an initiating loader for the class */
528 /* this is needed so subsequent code can assume that self-refs */
529 /* will always resolve lazily */
530 /* No need to do it for the bootloader - it is always registered */
531 /* as initiating loader for the classes it loads. */
533 classcache_store(c->classloader,c,false);
535 /* this class is currently linking */
537 c->state |= CLASS_LINKING;
542 /* check interfaces */
544 for (i = 0; i < c->interfacescount; i++) {
545 /* resolve this super interface */
547 if ((tc = resolve_classref_or_classinfo_eager(c->interfaces[i], true)) == NULL)
550 c->interfaces[i].cls = tc;
552 /* detect circularity */
555 exceptions_throw_classcircularityerror(c);
559 assert(tc->state & CLASS_LOADED);
561 if (!(tc->flags & ACC_INTERFACE)) {
562 exceptions_throw_incompatibleclasschangeerror(tc,
563 "Implementing class");
567 if (!(tc->state & CLASS_LINKED))
572 /* check super class */
576 if (c->super.any == NULL) { /* class java.lang.Object */
578 c->instancesize = sizeof(java_object_t);
580 vftbllength = supervftbllength = 0;
585 /* resolve super class */
587 if ((super = resolve_classref_or_classinfo_eager(c->super, true)) == NULL)
590 c->super.cls = super;
592 /* detect circularity */
595 exceptions_throw_classcircularityerror(c);
599 assert(super->state & CLASS_LOADED);
601 if (super->flags & ACC_INTERFACE) {
602 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
603 log_text("Interface specified as super class");
607 /* Don't allow extending final classes */
609 if (super->flags & ACC_FINAL) {
610 exceptions_throw_verifyerror(NULL,
611 "Cannot inherit from final class");
615 /* link the superclass if necessary */
617 if (!(super->state & CLASS_LINKED))
618 if (!link_class(super))
621 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
624 c->flags |= (super->flags &
625 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
627 /* handle array classes */
629 if (c->name->text[0] == '[')
630 if (!(arraydesc = link_array(c)))
633 if (c->flags & ACC_INTERFACE)
634 c->index = interfaceindex++;
636 c->index = super->index + 1;
638 c->instancesize = super->instancesize;
640 vftbllength = supervftbllength = super->vftbl->vftbllength;
642 c->finalizer = super->finalizer;
644 RT_TIMING_GET_TIME(time_resolving);
647 /* compute vftbl length */
649 for (i = 0; i < c->methodscount; i++) {
650 methodinfo *m = &(c->methods[i]);
652 if (!(m->flags & ACC_STATIC)) { /* is instance method */
658 for (j = 0; j < tc->methodscount; j++) {
659 if (method_canoverwrite(m, &(tc->methods[j]))) {
660 if (tc->methods[j].flags & ACC_PRIVATE)
661 goto notfoundvftblindex;
663 /* package-private methods in other packages */
664 /* must not be overridden */
665 /* (see Java Language Specification 8.4.8.1) */
666 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
667 && !SAME_PACKAGE(c,tc) )
669 goto notfoundvftblindex;
672 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
675 goto foundvftblindex;
683 m->vftblindex = (vftbllength++);
688 RT_TIMING_GET_TIME(time_compute_vftbl);
691 /* Check all interfaces of an abstract class (maybe be an
692 interface too) for unimplemented methods. Such methods are
693 called miranda-methods and are marked with the ACC_MIRANDA
694 flag. VMClass.getDeclaredMethods does not return such
697 if (c->flags & ACC_ABSTRACT) {
700 s4 abstractmethodscount;
704 abstractmethodscount = 0;
706 /* check all interfaces of the abstract class */
708 for (i = 0; i < c->interfacescount; i++) {
709 ic = c->interfaces[i].cls;
711 for (j = 0; j < ic->methodscount; j++) {
712 im = &(ic->methods[j]);
714 /* skip `<clinit>' and `<init>' */
716 if ((im->name == utf_clinit) || (im->name == utf_init))
719 for (tc = c; tc != NULL; tc = tc->super.cls) {
720 for (k = 0; k < tc->methodscount; k++) {
721 if (method_canoverwrite(im, &(tc->methods[k])))
722 goto noabstractmethod;
726 abstractmethodscount++;
733 if (abstractmethodscount > 0) {
736 /* reallocate methods memory */
738 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
739 c->methodscount + abstractmethodscount);
741 for (i = 0; i < c->interfacescount; i++) {
742 ic = c->interfaces[i].cls;
744 for (j = 0; j < ic->methodscount; j++) {
745 im = &(ic->methods[j]);
747 /* skip `<clinit>' and `<init>' */
749 if ((im->name == utf_clinit) || (im->name == utf_init))
752 for (tc = c; tc != NULL; tc = tc->super.cls) {
753 for (k = 0; k < tc->methodscount; k++) {
754 if (method_canoverwrite(im, &(tc->methods[k])))
755 goto noabstractmethod2;
759 /* Copy the method found into the new c->methods
760 array and tag it as miranda-method. */
762 am = &(c->methods[c->methodscount]);
765 MCOPY(am, im, methodinfo, 1);
767 am->vftblindex = (vftbllength++);
769 am->flags |= ACC_MIRANDA;
777 RT_TIMING_GET_TIME(time_abstract);
780 #if defined(ENABLE_STATISTICS)
783 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
786 /* compute interfacetable length */
788 interfacetablelength = 0;
790 for (tc = c; tc != NULL; tc = tc->super.cls) {
791 for (i = 0; i < tc->interfacescount; i++) {
792 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
794 if (h > interfacetablelength)
795 interfacetablelength = h;
798 RT_TIMING_GET_TIME(time_compute_iftbl);
800 /* allocate virtual function table */
802 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
803 sizeof(methodptr) * (vftbllength - 1) +
804 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
805 v = (vftbl_t *) (((methodptr *) v) +
806 (interfacetablelength - 1) * (interfacetablelength > 1));
810 v->vftbllength = vftbllength;
811 v->interfacetablelength = interfacetablelength;
812 v->arraydesc = arraydesc;
814 /* store interface index in vftbl */
816 if (c->flags & ACC_INTERFACE)
817 v->baseval = -(c->index);
819 /* copy virtual function table of super class */
821 for (i = 0; i < supervftbllength; i++)
822 v->table[i] = super->vftbl->table[i];
824 /* Fill the remaining vftbl slots with the AbstractMethodError
825 stub (all after the super class slots, because they are already
828 for (; i < vftbllength; i++) {
829 #if defined(ENABLE_JIT)
830 # if defined(ENABLE_INTRP)
832 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
835 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
837 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
841 /* add method stubs into virtual function table */
843 for (i = 0; i < c->methodscount; i++) {
844 methodinfo *m = &(c->methods[i]);
846 assert(m->stubroutine == NULL);
848 /* Don't create a compiler stub for abstract methods as they
849 throw an AbstractMethodError with the default stub in the
850 vftbl. This entry is simply copied by sub-classes. */
852 if (m->flags & ACC_ABSTRACT)
855 #if defined(ENABLE_JIT)
856 # if defined(ENABLE_INTRP)
858 m->stubroutine = intrp_createcompilerstub(m);
861 m->stubroutine = codegen_generate_stub_compiler(m);
863 m->stubroutine = intrp_createcompilerstub(m);
866 /* static methods are not in the vftbl */
868 if (m->flags & ACC_STATIC)
871 /* insert the stubroutine into the vftbl */
873 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
875 RT_TIMING_GET_TIME(time_fill_vftbl);
877 /* compute instance size and offset of each field */
879 for (i = 0; i < c->fieldscount; i++) {
881 fieldinfo *f = &(c->fields[i]);
883 if (!(f->flags & ACC_STATIC)) {
884 dsize = descriptor_typesize(f->parseddesc);
886 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
887 /* On i386 and ARM we align double and s8 fields to
888 4-bytes. This matches what GCC does for struct
889 members. We must do the same as gcc here because the
890 offsets in native header structs like java_lang_Double
891 must match the offsets of the Java fields
892 (eg. java.lang.Double.value). */
894 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
896 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
899 f->offset = c->instancesize;
900 c->instancesize += dsize;
903 RT_TIMING_GET_TIME(time_offsets);
905 /* initialize interfacetable and interfacevftbllength */
907 v->interfacevftbllength = MNEW(s4, interfacetablelength);
909 #if defined(ENABLE_STATISTICS)
911 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
914 for (i = 0; i < interfacetablelength; i++) {
915 v->interfacevftbllength[i] = 0;
916 v->interfacetable[-i] = NULL;
921 for (tc = c; tc != NULL; tc = tc->super.cls)
922 for (i = 0; i < tc->interfacescount; i++)
923 if (!linker_addinterface(c, tc->interfaces[i].cls))
926 RT_TIMING_GET_TIME(time_fill_iftbl);
928 /* add finalizer method (not for java.lang.Object) */
933 fi = class_findmethod(c, utf_finalize, utf_void__void);
936 if (!(fi->flags & ACC_STATIC))
939 RT_TIMING_GET_TIME(time_finalizer);
943 linker_compute_subclasses(c);
945 RT_TIMING_GET_TIME(time_subclasses);
947 /* revert the linking state and class is linked */
949 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
953 /* XXX must this also be done in case of exception? */
955 while (worklist != NULL) {
956 method_worklist *wi = worklist;
958 worklist = worklist->next;
960 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
961 jit_invalidate_code(wi->m);
963 /* XXX put worklist into dump memory? */
964 FREE(wi, method_worklist);
969 log_message_class("Linking done class: ", c);
972 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
973 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
974 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
975 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
976 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
977 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
978 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
979 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
980 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
982 /* just return c to show that we didn't had a problem */
988 /* link_array ******************************************************************
990 This function is called by link_class to create the arraydescriptor
993 This function returns NULL if the array cannot be linked because
994 the component type has not been linked yet.
996 *******************************************************************************/
998 static arraydescriptor *link_array(classinfo *c)
1002 arraydescriptor *desc;
1007 namelen = c->name->blength;
1009 /* Check the component type */
1011 switch (c->name->text[1]) {
1013 /* c is an array of arrays. */
1014 u = utf_new(c->name->text + 1, namelen - 1);
1015 if (!(comp = load_class_from_classloader(u, c->classloader)))
1020 /* c is an array of objects. */
1021 u = utf_new(c->name->text + 2, namelen - 3);
1022 if (!(comp = load_class_from_classloader(u, c->classloader)))
1027 /* If the component type has not been linked, link it now */
1029 assert(!comp || (comp->state & CLASS_LOADED));
1031 if (comp && !(comp->state & CLASS_LINKED))
1032 if (!link_class(comp))
1035 /* Allocate the arraydescriptor */
1037 desc = NEW(arraydescriptor);
1040 /* c is an array of references */
1041 desc->arraytype = ARRAYTYPE_OBJECT;
1042 desc->componentsize = sizeof(void*);
1043 desc->dataoffset = OFFSET(java_objectarray_t, data);
1045 compvftbl = comp->vftbl;
1048 log_text("Component class has no vftbl");
1052 desc->componentvftbl = compvftbl;
1054 if (compvftbl->arraydesc) {
1055 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1057 if (compvftbl->arraydesc->dimension >= 255) {
1058 log_text("Creating array of dimension >255");
1062 desc->dimension = compvftbl->arraydesc->dimension + 1;
1063 desc->elementtype = compvftbl->arraydesc->elementtype;
1066 desc->elementvftbl = compvftbl;
1067 desc->dimension = 1;
1068 desc->elementtype = ARRAYTYPE_OBJECT;
1072 /* c is an array of a primitive type */
1073 switch (c->name->text[1]) {
1075 desc->arraytype = ARRAYTYPE_BOOLEAN;
1076 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1077 desc->componentsize = sizeof(u1);
1081 desc->arraytype = ARRAYTYPE_BYTE;
1082 desc->dataoffset = OFFSET(java_bytearray_t,data);
1083 desc->componentsize = sizeof(u1);
1087 desc->arraytype = ARRAYTYPE_CHAR;
1088 desc->dataoffset = OFFSET(java_chararray_t,data);
1089 desc->componentsize = sizeof(u2);
1093 desc->arraytype = ARRAYTYPE_DOUBLE;
1094 desc->dataoffset = OFFSET(java_doublearray_t,data);
1095 desc->componentsize = sizeof(double);
1099 desc->arraytype = ARRAYTYPE_FLOAT;
1100 desc->dataoffset = OFFSET(java_floatarray_t,data);
1101 desc->componentsize = sizeof(float);
1105 desc->arraytype = ARRAYTYPE_INT;
1106 desc->dataoffset = OFFSET(java_intarray_t,data);
1107 desc->componentsize = sizeof(s4);
1111 desc->arraytype = ARRAYTYPE_LONG;
1112 desc->dataoffset = OFFSET(java_longarray_t,data);
1113 desc->componentsize = sizeof(s8);
1117 desc->arraytype = ARRAYTYPE_SHORT;
1118 desc->dataoffset = OFFSET(java_shortarray_t,data);
1119 desc->componentsize = sizeof(s2);
1123 exceptions_throw_noclassdeffounderror(c->name);
1127 desc->componentvftbl = NULL;
1128 desc->elementvftbl = NULL;
1129 desc->dimension = 1;
1130 desc->elementtype = desc->arraytype;
1137 /* linker_compute_subclasses ***************************************************
1141 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1142 This function needs to take the class renumber lock and stop the
1143 world during class renumbering. The lock is used in C code which
1144 is not that performance critical. Whereas JIT code uses critical
1145 sections to atomically access the class values.
1147 *******************************************************************************/
1149 static void linker_compute_subclasses(classinfo *c)
1151 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1153 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1154 threads_cast_stopworld();
1157 if (!(c->flags & ACC_INTERFACE)) {
1162 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1163 c->nextsub = c->super.cls->sub;
1164 c->super.cls->sub = c;
1169 /* compute class values */
1171 linker_compute_class_values(class_java_lang_Object);
1173 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1175 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1176 threads_cast_startworld();
1181 /* linker_compute_class_values *************************************************
1185 *******************************************************************************/
1187 static void linker_compute_class_values(classinfo *c)
1191 c->vftbl->baseval = ++classvalue;
1196 linker_compute_class_values(subs);
1198 subs = subs->nextsub;
1201 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1205 /* linker_addinterface *********************************************************
1207 Is needed by link_class for adding a VTBL to a class. All
1208 interfaces implemented by ic are added as well.
1211 true.........everything ok
1212 false........an exception has been thrown
1214 *******************************************************************************/
1216 static bool linker_addinterface(classinfo *c, classinfo *ic)
1227 if (i >= v->interfacetablelength)
1228 vm_abort("Internal error: interfacetable overflow");
1230 /* if this interface has already been added, return immediately */
1232 if (v->interfacetable[-i] != NULL)
1235 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1236 v->interfacevftbllength[i] = 1;
1237 v->interfacetable[-i] = MNEW(methodptr, 1);
1238 v->interfacetable[-i][0] = NULL;
1241 v->interfacevftbllength[i] = ic->methodscount;
1242 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1244 #if defined(ENABLE_STATISTICS)
1246 count_vftbl_len += sizeof(methodptr) *
1247 (ic->methodscount + (ic->methodscount == 0));
1250 for (j = 0; j < ic->methodscount; j++) {
1251 for (sc = c; sc != NULL; sc = sc->super.cls) {
1252 for (k = 0; k < sc->methodscount; k++) {
1253 m = &(sc->methods[k]);
1255 if (method_canoverwrite(m, &(ic->methods[j]))) {
1256 /* method m overwrites the (abstract) method */
1257 #if defined(ENABLE_VERIFIER)
1258 /* Add loading constraints (for the more
1259 general types of the method
1261 if (!classcache_add_constraints_for_params(
1262 c->classloader, ic->classloader,
1269 /* XXX taken from gcj */
1270 /* check for ACC_STATIC: IncompatibleClassChangeError */
1272 /* check for !ACC_PUBLIC: IllegalAccessError */
1274 /* check for ACC_ABSTRACT: AbstracMethodError,
1275 not sure about that one */
1277 v->interfacetable[-i][j] = v->table[m->vftblindex];
1283 /* If no method was found, insert the AbstractMethodError
1286 #if defined(ENABLE_JIT)
1287 # if defined(ENABLE_INTRP)
1289 v->interfacetable[-i][j] =
1290 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1293 v->interfacetable[-i][j] =
1294 (methodptr) (ptrint) &asm_abstractmethoderror;
1296 v->interfacetable[-i][j] =
1297 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1305 /* add superinterfaces of this interface */
1307 for (j = 0; j < ic->interfacescount; j++)
1308 if (!linker_addinterface(c, ic->interfaces[j].cls))
1317 /* class_highestinterface ******************************************************
1319 Used by the function link_class to determine the amount of memory
1320 needed for the interface table.
1322 *******************************************************************************/
1324 static s4 class_highestinterface(classinfo *c)
1330 /* check for ACC_INTERFACE bit already done in link_class_intern */
1334 for (i = 0; i < c->interfacescount; i++) {
1335 h2 = class_highestinterface(c->interfaces[i].cls);
1346 * These are local overrides for various environment variables in Emacs.
1347 * Please do not remove this and leave it at the end of the file, where
1348 * Emacs will automagically detect them.
1349 * ---------------------------------------------------------------------
1352 * indent-tabs-mode: t
1356 * vim:noexpandtab:sw=4:ts=4: