1 /* src/vm/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "native/native.h"
37 #include "threads/lock-common.h"
38 #include "threads/mutex.hpp"
40 #include "toolbox/logging.h"
42 #include "vm/access.h"
45 #include "vm/classcache.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/globals.hpp"
48 #include "vm/loader.hpp"
49 #include "vm/options.h"
50 #include "vm/primitive.hpp"
51 #include "vm/rt-timing.h"
52 #include "vm/string.hpp"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/stubs.hpp"
59 /* debugging macros ***********************************************************/
62 # define TRACELINKCLASS(c) \
64 if (opt_TraceLinkClass) { \
66 log_print("[Linking "); \
73 # define TRACELINKCLASS(c)
77 /* #include "vm/resolve.h" */
78 /* copied prototype to avoid bootstrapping problem: */
79 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
81 #if defined(ENABLE_STATISTICS)
82 # include "vm/statistics.h"
85 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
86 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
88 #define INLINELOG(code)
92 /* global variables ***********************************************************/
94 static s4 interfaceindex; /* sequential numbering of interfaces */
98 /* private functions **********************************************************/
100 static classinfo *link_class_intern(classinfo *c);
101 static arraydescriptor *link_array(classinfo *c);
102 static void linker_compute_class_values(classinfo *c);
103 static void linker_compute_subclasses(classinfo *c);
104 static bool linker_addinterface(classinfo *c, classinfo *ic);
105 static s4 class_highestinterface(classinfo *c);
108 /* linker_init *****************************************************************
110 Initializes the linker subsystem and links classes required for the
113 *******************************************************************************/
115 void linker_preinit(void)
117 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
119 /* Reset interface index. */
123 /* Link the most basic classes. */
125 if (!link_class(class_java_lang_Object))
126 vm_abort("linker_preinit: linking java/lang/Object failed");
128 #if defined(ENABLE_JAVASE)
129 if (!link_class(class_java_lang_Cloneable))
130 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
132 if (!link_class(class_java_io_Serializable))
133 vm_abort("linker_preinit: linking java/io/Serializable failed");
138 /* linker_init *****************************************************************
140 Links all classes required in the VM.
142 *******************************************************************************/
144 void linker_init(void)
146 TRACESUBSYSTEMINITIALIZATION("linker_init");
148 /* Link java.lang.Class as first class of the system, because we
149 need it's vftbl for all other classes so we can use a class as
152 if (!link_class(class_java_lang_Class))
153 vm_abort("linker_init: linking java/lang/Class failed");
155 /* Now set the header.vftbl of all classes which were created
156 before java.lang.Class was linked. */
158 class_postset_header_vftbl();
160 /* Link primitive-type wrapping classes. */
162 #if defined(ENABLE_JAVASE)
163 if (!link_class(class_java_lang_Void))
164 vm_abort("linker_init: linking failed");
167 if (!link_class(class_java_lang_Boolean))
168 vm_abort("linker_init: linking failed");
170 if (!link_class(class_java_lang_Byte))
171 vm_abort("linker_init: linking failed");
173 if (!link_class(class_java_lang_Character))
174 vm_abort("linker_init: linking failed");
176 if (!link_class(class_java_lang_Short))
177 vm_abort("linker_init: linking failed");
179 if (!link_class(class_java_lang_Integer))
180 vm_abort("linker_init: linking failed");
182 if (!link_class(class_java_lang_Long))
183 vm_abort("linker_init: linking failed");
185 if (!link_class(class_java_lang_Float))
186 vm_abort("linker_init: linking failed");
188 if (!link_class(class_java_lang_Double))
189 vm_abort("linker_init: linking failed");
191 /* Link important system classes. */
193 if (!link_class(class_java_lang_String))
194 vm_abort("linker_init: linking java/lang/String failed");
196 #if defined(ENABLE_JAVASE)
197 if (!link_class(class_java_lang_ClassLoader))
198 vm_abort("linker_init: linking failed");
200 if (!link_class(class_java_lang_SecurityManager))
201 vm_abort("linker_init: linking failed");
204 if (!link_class(class_java_lang_System))
205 vm_abort("linker_init: linking failed");
207 if (!link_class(class_java_lang_Thread))
208 vm_abort("linker_init: linking failed");
210 #if defined(ENABLE_JAVASE)
211 if (!link_class(class_java_lang_ThreadGroup))
212 vm_abort("linker_init: linking failed");
215 if (!link_class(class_java_lang_Throwable))
216 vm_abort("linker_init: linking failed");
218 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
219 if (!link_class(class_java_lang_VMSystem))
220 vm_abort("linker_init: linking failed");
222 if (!link_class(class_java_lang_VMThread))
223 vm_abort("linker_init: linking failed");
225 if (!link_class(class_java_lang_VMThrowable))
226 vm_abort("linker_init: linking failed");
229 /* Important system exceptions. */
231 if (!link_class(class_java_lang_Exception))
232 vm_abort("linker_init: linking failed");
234 if (!link_class(class_java_lang_ClassNotFoundException))
235 vm_abort("linker_init: linking failed");
237 if (!link_class(class_java_lang_RuntimeException))
238 vm_abort("linker_init: linking failed");
240 /* some classes which may be used more often */
242 #if defined(ENABLE_JAVASE)
243 if (!link_class(class_java_lang_StackTraceElement))
244 vm_abort("linker_init: linking failed");
246 if (!link_class(class_java_lang_reflect_Constructor))
247 vm_abort("linker_init: linking failed");
249 if (!link_class(class_java_lang_reflect_Field))
250 vm_abort("linker_init: linking failed");
252 if (!link_class(class_java_lang_reflect_Method))
253 vm_abort("linker_init: linking failed");
255 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
256 if (!link_class(class_java_lang_reflect_VMConstructor))
257 vm_abort("linker_init: linking failed");
259 if (!link_class(class_java_lang_reflect_VMField))
260 vm_abort("linker_init: linking failed");
262 if (!link_class(class_java_lang_reflect_VMMethod))
263 vm_abort("linker_init: linking failed");
266 if (!link_class(class_java_security_PrivilegedAction))
267 vm_abort("linker_init: linking failed");
269 if (!link_class(class_java_util_Vector))
270 vm_abort("linker_init: linking failed");
272 if (!link_class(class_java_util_HashMap))
273 vm_abort("linker_init: linking failed");
275 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
276 if (!link_class(class_sun_misc_Signal))
277 vm_abort("linker_init: linking failed");
279 if (!link_class(class_sun_reflect_MagicAccessorImpl))
280 vm_abort("linker_init: linking failed");
283 if (!link_class(arrayclass_java_lang_Object))
284 vm_abort("linker_init: linking failed");
288 /* create pseudo classes used by the typechecker */
290 /* pseudo class for Arraystubs (extends java.lang.Object) */
292 pseudo_class_Arraystub =
293 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
294 pseudo_class_Arraystub->state |= CLASS_LOADED;
295 pseudo_class_Arraystub->super = class_java_lang_Object;
297 #if defined(ENABLE_JAVASE)
299 pseudo_class_Arraystub->interfacescount = 2;
300 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
301 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
302 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
304 #elif defined(ENABLE_JAVAME_CLDC1_1)
306 pseudo_class_Arraystub->interfacescount = 0;
307 pseudo_class_Arraystub->interfaces = NULL;
310 # error unknown Java configuration
313 if (!classcache_store_unique(pseudo_class_Arraystub))
314 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
316 if (!link_class(pseudo_class_Arraystub))
317 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
319 /* pseudo class representing the null type */
321 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
322 pseudo_class_Null->state |= CLASS_LOADED;
323 pseudo_class_Null->super = class_java_lang_Object;
325 if (!classcache_store_unique(pseudo_class_Null))
326 vm_abort("linker_init: could not cache pseudo_class_Null");
328 if (!link_class(pseudo_class_Null))
329 vm_abort("linker_init: linking failed");
331 /* pseudo class representing new uninitialized objects */
333 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
334 pseudo_class_New->state |= CLASS_LOADED;
335 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
336 pseudo_class_New->super = class_java_lang_Object;
338 if (!classcache_store_unique(pseudo_class_New))
339 vm_abort("linker_init: could not cache pseudo_class_New");
341 /* Correct vftbl-entries (retarded loading and linking of class
342 java/lang/String). */
344 stringtable_update();
348 /* link_class ******************************************************************
350 Wrapper function for link_class_intern to ease monitor enter/exit
351 and exception handling.
353 *******************************************************************************/
355 classinfo *link_class(classinfo *c)
358 #if defined(ENABLE_RT_TIMING)
359 struct timespec time_start, time_end;
362 RT_TIMING_GET_TIME(time_start);
365 exceptions_throw_nullpointerexception();
369 LOCK_MONITOR_ENTER(c);
371 /* Maybe the class is currently linking or is already linked.*/
373 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
374 LOCK_MONITOR_EXIT(c);
379 #if defined(ENABLE_STATISTICS)
382 if (opt_getcompilingtime)
383 compilingtime_stop();
385 if (opt_getloadingtime)
389 /* call the internal function */
391 r = link_class_intern(c);
393 /* If return value is NULL, we had a problem and the class is not
397 c->state &= ~CLASS_LINKING;
399 #if defined(ENABLE_STATISTICS)
402 if (opt_getloadingtime)
405 if (opt_getcompilingtime)
406 compilingtime_start();
409 LOCK_MONITOR_EXIT(c);
411 RT_TIMING_GET_TIME(time_end);
413 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
419 /* linker_overwrite_method *****************************************************
421 Overwrite a method with another one, update method flags and check
425 mg................the general method being overwritten
426 ms................the overwriting (more specialized) method
427 wl................worklist where to add invalidated methods
430 true..............everything ok
431 false.............an exception has been thrown
433 *******************************************************************************/
435 static bool linker_overwrite_method(methodinfo *mg,
437 method_worklist **wl)
445 /* overriding a final method is illegal */
447 if (mg->flags & ACC_FINAL) {
448 exceptions_throw_verifyerror(mg, "Overriding final method");
452 /* method ms overwrites method mg */
454 #if defined(ENABLE_VERIFIER)
455 /* Add loading constraints (for the more general types of method mg). */
456 /* Not for <init>, as it is not invoked virtually. */
458 if ((ms->name != utf_init)
459 && !classcache_add_constraints_for_params(
460 cs->classloader, cg->classloader, mg))
466 /* inherit the vftbl index, and record the overwriting */
468 ms->vftblindex = mg->vftblindex;
471 /* update flags and check assumptions */
472 /* <init> methods are a special case, as they are never dispatched dynamically */
474 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
477 #if defined(ENABLE_TLH)
478 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
479 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
480 ms->clazz->name->text, ms->name->text);
481 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
485 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
486 /* this adds another implementation */
488 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
490 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
492 method_break_assumption_monomorphic(mg, wl);
495 /* this is the first implementation */
497 mg->flags |= ACC_METHOD_IMPLEMENTED;
499 INLINELOG( printf("becomes implemented: "); method_println(mg); );
504 } while (mg != NULL);
511 /* link_class_intern ***********************************************************
513 Tries to link a class. The function calculates the length in bytes
514 that an instance of this class requires as well as the VTBL for
515 methods and interface methods.
517 *******************************************************************************/
519 static int build_display_inner(classinfo *topc, classinfo *c, int i)
525 if (c->vftbl->arraydesc)
527 arraydescriptor *a = c->vftbl->arraydesc;
528 if (a->elementvftbl && a->elementvftbl->clazz->super)
530 classinfo *cls = a->elementvftbl->clazz->super;
532 for (n=0; n<a->dimension; n++)
533 cls = class_array_of(cls, true);
534 depth = build_display_inner(topc, cls, i+1);
537 if (a->componentvftbl && a->elementvftbl)
539 depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
543 depth = build_display_inner(topc, c->super, i+1);
545 if (depth >= DISPLAY_SIZE)
547 if (depth == DISPLAY_SIZE)
549 topc->vftbl->subtype_overflow = malloc(sizeof(void*) * (i+1));
550 #if defined(ENABLE_STATISTICS)
552 count_vftbl_len += sizeof(void*) * (i+1);
555 topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
558 topc->vftbl->subtype_display[depth] = c->vftbl;
562 static void build_display(classinfo *c)
567 depth = build_display_inner(c, c, 0) - 1;
568 c->vftbl->subtype_depth = depth;
569 if (depth >= DISPLAY_SIZE)
571 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
575 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
576 for (i=depth+1; i<=DISPLAY_SIZE; i++)
577 c->vftbl->subtype_display[i] = NULL;
581 static classinfo *link_class_intern(classinfo *c)
583 classinfo *super; /* super class */
584 classinfo *tc; /* temporary class variable */
585 s4 supervftbllength; /* vftbllegnth of super class */
586 s4 vftbllength; /* vftbllength of current class */
587 s4 interfacetablelength; /* interface table length */
588 vftbl_t *v; /* vftbl of current class */
589 s4 i; /* interface/method/field counter */
590 arraydescriptor *arraydesc; /* descriptor for array classes */
591 method_worklist *worklist; /* worklist for recompilation */
592 #if defined(ENABLE_RT_TIMING)
593 struct timespec time_start, time_resolving, time_compute_vftbl,
594 time_abstract, time_compute_iftbl, time_fill_vftbl,
595 time_offsets, time_fill_iftbl, time_finalizer,
599 RT_TIMING_GET_TIME(time_start);
603 /* the class must be loaded */
605 /* XXX should this be a specific exception? */
606 assert(c->state & CLASS_LOADED);
608 /* This is check in link_class. */
610 assert(!(c->state & CLASS_LINKED));
612 /* cache the self-reference of this class */
613 /* we do this for cases where the defining loader of the class */
614 /* has not yet been recorded as an initiating loader for the class */
615 /* this is needed so subsequent code can assume that self-refs */
616 /* will always resolve lazily */
617 /* No need to do it for the bootloader - it is always registered */
618 /* as initiating loader for the classes it loads. */
620 classcache_store(c->classloader,c,false);
622 /* this class is currently linking */
624 c->state |= CLASS_LINKING;
629 /* Link the super interfaces. */
631 for (i = 0; i < c->interfacescount; i++) {
632 tc = c->interfaces[i];
634 if (!(tc->state & CLASS_LINKED))
639 /* check super class */
643 /* Check for java/lang/Object. */
645 if (c->super == NULL) {
647 c->instancesize = sizeof(java_object_t);
649 vftbllength = supervftbllength = 0;
654 /* Get super class. */
658 /* Link the super class if necessary. */
660 if (!(super->state & CLASS_LINKED))
661 if (!link_class(super))
664 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
667 c->flags |= (super->flags &
668 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
670 /* handle array classes */
672 if (c->name->text[0] == '[')
673 if (!(arraydesc = link_array(c)))
676 if (c->flags & ACC_INTERFACE)
677 c->index = interfaceindex++;
679 c->index = super->index + 1;
681 c->instancesize = super->instancesize;
683 vftbllength = supervftbllength = super->vftbl->vftbllength;
685 c->finalizer = super->finalizer;
687 RT_TIMING_GET_TIME(time_resolving);
690 /* compute vftbl length */
692 for (i = 0; i < c->methodscount; i++) {
693 methodinfo *m = &(c->methods[i]);
695 if (!(m->flags & ACC_STATIC)) { /* is instance method */
701 for (j = 0; j < tc->methodscount; j++) {
702 if (method_canoverwrite(m, &(tc->methods[j]))) {
703 if (tc->methods[j].flags & ACC_PRIVATE)
704 goto notfoundvftblindex;
706 /* package-private methods in other packages */
707 /* must not be overridden */
708 /* (see Java Language Specification 8.4.8.1) */
709 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
710 && !SAME_PACKAGE(c,tc) )
712 goto notfoundvftblindex;
715 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
718 goto foundvftblindex;
726 m->vftblindex = (vftbllength++);
731 RT_TIMING_GET_TIME(time_compute_vftbl);
734 /* Check all interfaces of an abstract class (maybe be an
735 interface too) for unimplemented methods. Such methods are
736 called miranda-methods and are marked with the ACC_MIRANDA
737 flag. VMClass.getDeclaredMethods does not return such
740 if (c->flags & ACC_ABSTRACT) {
743 s4 abstractmethodscount;
747 abstractmethodscount = 0;
749 /* check all interfaces of the abstract class */
751 for (i = 0; i < c->interfacescount; i++) {
752 ic = c->interfaces[i];
754 for (j = 0; j < ic->methodscount; j++) {
755 im = &(ic->methods[j]);
757 /* skip `<clinit>' and `<init>' */
759 if ((im->name == utf_clinit) || (im->name == utf_init))
762 for (tc = c; tc != NULL; tc = tc->super) {
763 for (k = 0; k < tc->methodscount; k++) {
764 if (method_canoverwrite(im, &(tc->methods[k])))
765 goto noabstractmethod;
769 abstractmethodscount++;
776 if (abstractmethodscount > 0) {
779 /* reallocate methods memory */
781 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
782 c->methodscount + abstractmethodscount);
784 for (i = 0; i < c->interfacescount; i++) {
785 ic = c->interfaces[i];
787 for (j = 0; j < ic->methodscount; j++) {
788 im = &(ic->methods[j]);
790 /* skip `<clinit>' and `<init>' */
792 if ((im->name == utf_clinit) || (im->name == utf_init))
795 for (tc = c; tc != NULL; tc = tc->super) {
796 for (k = 0; k < tc->methodscount; k++) {
797 if (method_canoverwrite(im, &(tc->methods[k])))
798 goto noabstractmethod2;
802 /* Copy the method found into the new c->methods
803 array and tag it as miranda-method. */
805 am = &(c->methods[c->methodscount]);
808 MCOPY(am, im, methodinfo, 1);
810 am->vftblindex = (vftbllength++);
812 am->flags |= ACC_MIRANDA;
820 RT_TIMING_GET_TIME(time_abstract);
823 #if defined(ENABLE_STATISTICS)
826 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
829 /* compute interfacetable length */
831 interfacetablelength = 0;
833 for (tc = c; tc != NULL; tc = tc->super) {
834 for (i = 0; i < tc->interfacescount; i++) {
835 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
837 if (h > interfacetablelength)
838 interfacetablelength = h;
841 RT_TIMING_GET_TIME(time_compute_iftbl);
843 /* allocate virtual function table */
845 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
846 sizeof(methodptr) * (vftbllength - 1) +
847 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
848 v = (vftbl_t *) (((methodptr *) v) +
849 (interfacetablelength - 1) * (interfacetablelength > 1));
853 v->vftbllength = vftbllength;
854 v->interfacetablelength = interfacetablelength;
855 v->arraydesc = arraydesc;
857 /* store interface index in vftbl */
859 if (c->flags & ACC_INTERFACE)
860 v->baseval = -(c->index);
862 /* copy virtual function table of super class */
864 for (i = 0; i < supervftbllength; i++)
865 v->table[i] = super->vftbl->table[i];
867 /* Fill the remaining vftbl slots with the AbstractMethodError
868 stub (all after the super class slots, because they are already
871 for (; i < vftbllength; i++) {
872 #if defined(ENABLE_JIT)
873 # if defined(ENABLE_INTRP)
875 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
878 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
880 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
884 /* add method stubs into virtual function table */
886 for (i = 0; i < c->methodscount; i++) {
887 methodinfo *m = &(c->methods[i]);
889 assert(m->stubroutine == NULL);
891 /* Don't create a compiler stub for abstract methods as they
892 throw an AbstractMethodError with the default stub in the
893 vftbl. This entry is simply copied by sub-classes. */
895 if (m->flags & ACC_ABSTRACT)
898 #if defined(ENABLE_JIT)
899 # if defined(ENABLE_INTRP)
901 m->stubroutine = intrp_createcompilerstub(m);
904 m->stubroutine = CompilerStub_generate(m);
906 m->stubroutine = intrp_createcompilerstub(m);
909 /* static methods are not in the vftbl */
911 if (m->flags & ACC_STATIC)
914 /* insert the stubroutine into the vftbl */
916 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
918 RT_TIMING_GET_TIME(time_fill_vftbl);
920 /* compute instance size and offset of each field */
922 for (i = 0; i < c->fieldscount; i++) {
924 fieldinfo *f = &(c->fields[i]);
926 if (!(f->flags & ACC_STATIC)) {
927 dsize = descriptor_typesize(f->parseddesc);
928 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
929 f->offset = c->instancesize;
930 c->instancesize += dsize;
933 RT_TIMING_GET_TIME(time_offsets);
935 /* initialize interfacetable and interfacevftbllength */
937 v->interfacevftbllength = MNEW(s4, interfacetablelength);
939 #if defined(ENABLE_STATISTICS)
941 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
944 for (i = 0; i < interfacetablelength; i++) {
945 v->interfacevftbllength[i] = 0;
946 v->interfacetable[-i] = NULL;
951 for (tc = c; tc != NULL; tc = tc->super)
952 for (i = 0; i < tc->interfacescount; i++)
953 if (!linker_addinterface(c, tc->interfaces[i]))
956 RT_TIMING_GET_TIME(time_fill_iftbl);
958 /* add finalizer method (not for java.lang.Object) */
963 fi = class_findmethod(c, utf_finalize, utf_void__void);
966 if (!(fi->flags & ACC_STATIC))
969 RT_TIMING_GET_TIME(time_finalizer);
973 linker_compute_subclasses(c);
975 /* FIXME: this is completely useless now */
976 RT_TIMING_GET_TIME(time_subclasses);
980 /* revert the linking state and class is linked */
982 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
986 /* XXX must this also be done in case of exception? */
988 while (worklist != NULL) {
989 method_worklist *wi = worklist;
991 worklist = worklist->next;
993 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
994 jit_invalidate_code(wi->m);
996 /* XXX put worklist into dump memory? */
997 FREE(wi, method_worklist);
1000 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1001 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1002 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1003 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1004 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1005 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1006 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1007 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1008 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1010 /* just return c to show that we didn't had a problem */
1016 /* link_array ******************************************************************
1018 This function is called by link_class to create the arraydescriptor
1021 This function returns NULL if the array cannot be linked because
1022 the component type has not been linked yet.
1024 *******************************************************************************/
1026 static arraydescriptor *link_array(classinfo *c)
1030 arraydescriptor *desc;
1035 namelen = c->name->blength;
1037 /* Check the component type */
1039 switch (c->name->text[1]) {
1041 /* c is an array of arrays. */
1042 u = utf_new(c->name->text + 1, namelen - 1);
1043 if (!(comp = load_class_from_classloader(u, c->classloader)))
1048 /* c is an array of objects. */
1049 u = utf_new(c->name->text + 2, namelen - 3);
1050 if (!(comp = load_class_from_classloader(u, c->classloader)))
1055 /* If the component type has not been linked, link it now */
1057 assert(!comp || (comp->state & CLASS_LOADED));
1059 if (comp && !(comp->state & CLASS_LINKED))
1060 if (!link_class(comp))
1063 /* Allocate the arraydescriptor */
1065 desc = NEW(arraydescriptor);
1068 /* c is an array of references */
1069 desc->arraytype = ARRAYTYPE_OBJECT;
1070 desc->componentsize = sizeof(void*);
1071 desc->dataoffset = OFFSET(java_objectarray_t, data);
1073 compvftbl = comp->vftbl;
1076 log_text("Component class has no vftbl");
1080 desc->componentvftbl = compvftbl;
1082 if (compvftbl->arraydesc) {
1083 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1085 if (compvftbl->arraydesc->dimension >= 255) {
1086 log_text("Creating array of dimension >255");
1090 desc->dimension = compvftbl->arraydesc->dimension + 1;
1091 desc->elementtype = compvftbl->arraydesc->elementtype;
1094 desc->elementvftbl = compvftbl;
1095 desc->dimension = 1;
1096 desc->elementtype = ARRAYTYPE_OBJECT;
1100 /* c is an array of a primitive type */
1101 switch (c->name->text[1]) {
1103 desc->arraytype = ARRAYTYPE_BOOLEAN;
1104 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1105 desc->componentsize = sizeof(u1);
1109 desc->arraytype = ARRAYTYPE_BYTE;
1110 desc->dataoffset = OFFSET(java_bytearray_t,data);
1111 desc->componentsize = sizeof(u1);
1115 desc->arraytype = ARRAYTYPE_CHAR;
1116 desc->dataoffset = OFFSET(java_chararray_t,data);
1117 desc->componentsize = sizeof(u2);
1121 desc->arraytype = ARRAYTYPE_DOUBLE;
1122 desc->dataoffset = OFFSET(java_doublearray_t,data);
1123 desc->componentsize = sizeof(double);
1127 desc->arraytype = ARRAYTYPE_FLOAT;
1128 desc->dataoffset = OFFSET(java_floatarray_t,data);
1129 desc->componentsize = sizeof(float);
1133 desc->arraytype = ARRAYTYPE_INT;
1134 desc->dataoffset = OFFSET(java_intarray_t,data);
1135 desc->componentsize = sizeof(s4);
1139 desc->arraytype = ARRAYTYPE_LONG;
1140 desc->dataoffset = OFFSET(java_longarray_t,data);
1141 desc->componentsize = sizeof(s8);
1145 desc->arraytype = ARRAYTYPE_SHORT;
1146 desc->dataoffset = OFFSET(java_shortarray_t,data);
1147 desc->componentsize = sizeof(s2);
1151 exceptions_throw_noclassdeffounderror(c->name);
1155 desc->componentvftbl = NULL;
1156 desc->elementvftbl = NULL;
1157 desc->dimension = 1;
1158 desc->elementtype = desc->arraytype;
1165 /* linker_compute_subclasses ***************************************************
1169 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1170 This function needs to take the class renumber lock and stop the
1171 world during class renumbering. The lock is used in C code which
1172 is not that performance critical. Whereas JIT code uses critical
1173 sections to atomically access the class values.
1175 *******************************************************************************/
1177 static void linker_compute_subclasses(classinfo *c)
1180 if (!(c->flags & ACC_INTERFACE)) {
1183 c->vftbl->baseval = 1; /* so it does not look like an interface */
1186 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1187 c->nextsub = c->super->sub;
1196 /* linker_compute_class_values *************************************************
1200 *******************************************************************************/
1202 static void linker_compute_class_values(classinfo *c)
1206 c->vftbl->baseval = ++classvalue;
1211 linker_compute_class_values(subs);
1213 subs = subs->nextsub;
1216 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1220 /* linker_addinterface *********************************************************
1222 Is needed by link_class for adding a VTBL to a class. All
1223 interfaces implemented by ic are added as well.
1226 true.........everything ok
1227 false........an exception has been thrown
1229 *******************************************************************************/
1231 static bool linker_addinterface(classinfo *c, classinfo *ic)
1242 if (i >= v->interfacetablelength)
1243 vm_abort("Internal error: interfacetable overflow");
1245 /* if this interface has already been added, return immediately */
1247 if (v->interfacetable[-i] != NULL)
1250 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1251 v->interfacevftbllength[i] = 1;
1252 v->interfacetable[-i] = MNEW(methodptr, 1);
1253 v->interfacetable[-i][0] = NULL;
1256 v->interfacevftbllength[i] = ic->methodscount;
1257 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1259 #if defined(ENABLE_STATISTICS)
1261 count_vftbl_len += sizeof(methodptr) *
1262 (ic->methodscount + (ic->methodscount == 0));
1265 for (j = 0; j < ic->methodscount; j++) {
1266 for (sc = c; sc != NULL; sc = sc->super) {
1267 for (k = 0; k < sc->methodscount; k++) {
1268 m = &(sc->methods[k]);
1270 if (method_canoverwrite(m, &(ic->methods[j]))) {
1271 /* method m overwrites the (abstract) method */
1272 #if defined(ENABLE_VERIFIER)
1273 /* Add loading constraints (for the more
1274 general types of the method
1276 if (!classcache_add_constraints_for_params(
1277 c->classloader, ic->classloader,
1284 /* XXX taken from gcj */
1285 /* check for ACC_STATIC: IncompatibleClassChangeError */
1287 /* check for !ACC_PUBLIC: IllegalAccessError */
1289 /* check for ACC_ABSTRACT: AbstracMethodError,
1290 not sure about that one */
1292 v->interfacetable[-i][j] = v->table[m->vftblindex];
1298 /* If no method was found, insert the AbstractMethodError
1301 #if defined(ENABLE_JIT)
1302 # if defined(ENABLE_INTRP)
1304 v->interfacetable[-i][j] =
1305 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1308 v->interfacetable[-i][j] =
1309 (methodptr) (ptrint) &asm_abstractmethoderror;
1311 v->interfacetable[-i][j] =
1312 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1320 /* add superinterfaces of this interface */
1322 for (j = 0; j < ic->interfacescount; j++)
1323 if (!linker_addinterface(c, ic->interfaces[j]))
1332 /* class_highestinterface ******************************************************
1334 Used by the function link_class to determine the amount of memory
1335 needed for the interface table.
1337 *******************************************************************************/
1339 static s4 class_highestinterface(classinfo *c)
1345 /* check for ACC_INTERFACE bit already done in link_class_intern */
1349 for (i = 0; i < c->interfacescount; i++) {
1350 h2 = class_highestinterface(c->interfaces[i]);
1361 * These are local overrides for various environment variables in Emacs.
1362 * Please do not remove this and leave it at the end of the file, where
1363 * Emacs will automagically detect them.
1364 * ---------------------------------------------------------------------
1367 * indent-tabs-mode: t
1371 * vim:noexpandtab:sw=4:ts=4: