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_length = i+1;
550 topc->vftbl->subtype_overflow = malloc(sizeof(void*) * (i+1));
551 #if defined(ENABLE_STATISTICS)
553 count_vftbl_len += sizeof(void*) * (i+1);
556 topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
559 topc->vftbl->subtype_display[depth] = c->vftbl;
563 static void build_display(classinfo *c)
568 depth = build_display_inner(c, c, 0) - 1;
569 c->vftbl->subtype_depth = depth;
570 if (depth >= DISPLAY_SIZE)
572 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
576 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
577 for (i=depth+1; i<=DISPLAY_SIZE; i++)
578 c->vftbl->subtype_display[i] = NULL;
579 c->vftbl->subtype_overflow_length = 0;
583 static classinfo *link_class_intern(classinfo *c)
585 classinfo *super; /* super class */
586 classinfo *tc; /* temporary class variable */
587 s4 supervftbllength; /* vftbllegnth of super class */
588 s4 vftbllength; /* vftbllength of current class */
589 s4 interfacetablelength; /* interface table length */
590 vftbl_t *v; /* vftbl of current class */
591 s4 i; /* interface/method/field counter */
592 arraydescriptor *arraydesc; /* descriptor for array classes */
593 method_worklist *worklist; /* worklist for recompilation */
594 #if defined(ENABLE_RT_TIMING)
595 struct timespec time_start, time_resolving, time_compute_vftbl,
596 time_abstract, time_compute_iftbl, time_fill_vftbl,
597 time_offsets, time_fill_iftbl, time_finalizer,
601 RT_TIMING_GET_TIME(time_start);
605 /* the class must be loaded */
607 /* XXX should this be a specific exception? */
608 assert(c->state & CLASS_LOADED);
610 /* This is check in link_class. */
612 assert(!(c->state & CLASS_LINKED));
614 /* cache the self-reference of this class */
615 /* we do this for cases where the defining loader of the class */
616 /* has not yet been recorded as an initiating loader for the class */
617 /* this is needed so subsequent code can assume that self-refs */
618 /* will always resolve lazily */
619 /* No need to do it for the bootloader - it is always registered */
620 /* as initiating loader for the classes it loads. */
622 classcache_store(c->classloader,c,false);
624 /* this class is currently linking */
626 c->state |= CLASS_LINKING;
631 /* Link the super interfaces. */
633 for (i = 0; i < c->interfacescount; i++) {
634 tc = c->interfaces[i];
636 if (!(tc->state & CLASS_LINKED))
641 /* check super class */
645 /* Check for java/lang/Object. */
647 if (c->super == NULL) {
649 c->instancesize = sizeof(java_object_t);
651 vftbllength = supervftbllength = 0;
656 /* Get super class. */
660 /* Link the super class if necessary. */
662 if (!(super->state & CLASS_LINKED))
663 if (!link_class(super))
666 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
669 c->flags |= (super->flags &
670 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
672 /* handle array classes */
674 if (c->name->text[0] == '[')
675 if (!(arraydesc = link_array(c)))
678 if (c->flags & ACC_INTERFACE)
679 c->index = interfaceindex++;
681 c->index = super->index + 1;
683 c->instancesize = super->instancesize;
685 vftbllength = supervftbllength = super->vftbl->vftbllength;
687 c->finalizer = super->finalizer;
689 RT_TIMING_GET_TIME(time_resolving);
692 /* compute vftbl length */
694 for (i = 0; i < c->methodscount; i++) {
695 methodinfo *m = &(c->methods[i]);
697 if (!(m->flags & ACC_STATIC)) { /* is instance method */
703 for (j = 0; j < tc->methodscount; j++) {
704 if (method_canoverwrite(m, &(tc->methods[j]))) {
705 if (tc->methods[j].flags & ACC_PRIVATE)
706 goto notfoundvftblindex;
708 /* package-private methods in other packages */
709 /* must not be overridden */
710 /* (see Java Language Specification 8.4.8.1) */
711 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
712 && !SAME_PACKAGE(c,tc) )
714 goto notfoundvftblindex;
717 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
720 goto foundvftblindex;
728 m->vftblindex = (vftbllength++);
733 RT_TIMING_GET_TIME(time_compute_vftbl);
736 /* Check all interfaces of an abstract class (maybe be an
737 interface too) for unimplemented methods. Such methods are
738 called miranda-methods and are marked with the ACC_MIRANDA
739 flag. VMClass.getDeclaredMethods does not return such
742 if (c->flags & ACC_ABSTRACT) {
745 s4 abstractmethodscount;
749 abstractmethodscount = 0;
751 /* check all interfaces of the abstract class */
753 for (i = 0; i < c->interfacescount; i++) {
754 ic = c->interfaces[i];
756 for (j = 0; j < ic->methodscount; j++) {
757 im = &(ic->methods[j]);
759 /* skip `<clinit>' and `<init>' */
761 if ((im->name == utf_clinit) || (im->name == utf_init))
764 for (tc = c; tc != NULL; tc = tc->super) {
765 for (k = 0; k < tc->methodscount; k++) {
766 if (method_canoverwrite(im, &(tc->methods[k])))
767 goto noabstractmethod;
771 abstractmethodscount++;
778 if (abstractmethodscount > 0) {
781 /* reallocate methods memory */
783 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
784 c->methodscount + abstractmethodscount);
786 for (i = 0; i < c->interfacescount; i++) {
787 ic = c->interfaces[i];
789 for (j = 0; j < ic->methodscount; j++) {
790 im = &(ic->methods[j]);
792 /* skip `<clinit>' and `<init>' */
794 if ((im->name == utf_clinit) || (im->name == utf_init))
797 for (tc = c; tc != NULL; tc = tc->super) {
798 for (k = 0; k < tc->methodscount; k++) {
799 if (method_canoverwrite(im, &(tc->methods[k])))
800 goto noabstractmethod2;
804 /* Copy the method found into the new c->methods
805 array and tag it as miranda-method. */
807 am = &(c->methods[c->methodscount]);
810 MCOPY(am, im, methodinfo, 1);
812 am->vftblindex = (vftbllength++);
814 am->flags |= ACC_MIRANDA;
822 RT_TIMING_GET_TIME(time_abstract);
825 #if defined(ENABLE_STATISTICS)
828 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
831 /* compute interfacetable length */
833 interfacetablelength = 0;
835 for (tc = c; tc != NULL; tc = tc->super) {
836 for (i = 0; i < tc->interfacescount; i++) {
837 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
839 if (h > interfacetablelength)
840 interfacetablelength = h;
843 RT_TIMING_GET_TIME(time_compute_iftbl);
845 /* allocate virtual function table */
847 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
848 sizeof(methodptr) * (vftbllength - 1) +
849 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
850 v = (vftbl_t *) (((methodptr *) v) +
851 (interfacetablelength - 1) * (interfacetablelength > 1));
855 v->vftbllength = vftbllength;
856 v->interfacetablelength = interfacetablelength;
857 v->arraydesc = arraydesc;
859 /* store interface index in vftbl */
861 if (c->flags & ACC_INTERFACE)
862 v->baseval = -(c->index);
864 /* copy virtual function table of super class */
866 for (i = 0; i < supervftbllength; i++)
867 v->table[i] = super->vftbl->table[i];
869 /* Fill the remaining vftbl slots with the AbstractMethodError
870 stub (all after the super class slots, because they are already
873 for (; i < vftbllength; i++) {
874 #if defined(ENABLE_JIT)
875 # if defined(ENABLE_INTRP)
877 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
880 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
882 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
886 /* add method stubs into virtual function table */
888 for (i = 0; i < c->methodscount; i++) {
889 methodinfo *m = &(c->methods[i]);
891 assert(m->stubroutine == NULL);
893 /* Don't create a compiler stub for abstract methods as they
894 throw an AbstractMethodError with the default stub in the
895 vftbl. This entry is simply copied by sub-classes. */
897 if (m->flags & ACC_ABSTRACT)
900 #if defined(ENABLE_JIT)
901 # if defined(ENABLE_INTRP)
903 m->stubroutine = intrp_createcompilerstub(m);
906 m->stubroutine = CompilerStub_generate(m);
908 m->stubroutine = intrp_createcompilerstub(m);
911 /* static methods are not in the vftbl */
913 if (m->flags & ACC_STATIC)
916 /* insert the stubroutine into the vftbl */
918 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
920 RT_TIMING_GET_TIME(time_fill_vftbl);
922 /* compute instance size and offset of each field */
924 for (i = 0; i < c->fieldscount; i++) {
926 fieldinfo *f = &(c->fields[i]);
928 if (!(f->flags & ACC_STATIC)) {
929 dsize = descriptor_typesize(f->parseddesc);
930 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
931 f->offset = c->instancesize;
932 c->instancesize += dsize;
935 RT_TIMING_GET_TIME(time_offsets);
937 /* initialize interfacetable and interfacevftbllength */
939 v->interfacevftbllength = MNEW(s4, interfacetablelength);
941 #if defined(ENABLE_STATISTICS)
943 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
946 for (i = 0; i < interfacetablelength; i++) {
947 v->interfacevftbllength[i] = 0;
948 v->interfacetable[-i] = NULL;
953 for (tc = c; tc != NULL; tc = tc->super)
954 for (i = 0; i < tc->interfacescount; i++)
955 if (!linker_addinterface(c, tc->interfaces[i]))
958 RT_TIMING_GET_TIME(time_fill_iftbl);
960 /* add finalizer method (not for java.lang.Object) */
965 fi = class_findmethod(c, utf_finalize, utf_void__void);
968 if (!(fi->flags & ACC_STATIC))
971 RT_TIMING_GET_TIME(time_finalizer);
975 linker_compute_subclasses(c);
977 /* FIXME: this is completely useless now */
978 RT_TIMING_GET_TIME(time_subclasses);
982 /* revert the linking state and class is linked */
984 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
988 /* XXX must this also be done in case of exception? */
990 while (worklist != NULL) {
991 method_worklist *wi = worklist;
993 worklist = worklist->next;
995 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
996 jit_invalidate_code(wi->m);
998 /* XXX put worklist into dump memory? */
999 FREE(wi, method_worklist);
1002 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1003 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1004 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1005 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1006 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1007 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1008 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1009 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1010 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1012 /* just return c to show that we didn't had a problem */
1018 /* link_array ******************************************************************
1020 This function is called by link_class to create the arraydescriptor
1023 This function returns NULL if the array cannot be linked because
1024 the component type has not been linked yet.
1026 *******************************************************************************/
1028 static arraydescriptor *link_array(classinfo *c)
1032 arraydescriptor *desc;
1037 namelen = c->name->blength;
1039 /* Check the component type */
1041 switch (c->name->text[1]) {
1043 /* c is an array of arrays. */
1044 u = utf_new(c->name->text + 1, namelen - 1);
1045 if (!(comp = load_class_from_classloader(u, c->classloader)))
1050 /* c is an array of objects. */
1051 u = utf_new(c->name->text + 2, namelen - 3);
1052 if (!(comp = load_class_from_classloader(u, c->classloader)))
1057 /* If the component type has not been linked, link it now */
1059 assert(!comp || (comp->state & CLASS_LOADED));
1061 if (comp && !(comp->state & CLASS_LINKED))
1062 if (!link_class(comp))
1065 /* Allocate the arraydescriptor */
1067 desc = NEW(arraydescriptor);
1070 /* c is an array of references */
1071 desc->arraytype = ARRAYTYPE_OBJECT;
1072 desc->componentsize = sizeof(void*);
1073 desc->dataoffset = OFFSET(java_objectarray_t, data);
1075 compvftbl = comp->vftbl;
1078 log_text("Component class has no vftbl");
1082 desc->componentvftbl = compvftbl;
1084 if (compvftbl->arraydesc) {
1085 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1087 if (compvftbl->arraydesc->dimension >= 255) {
1088 log_text("Creating array of dimension >255");
1092 desc->dimension = compvftbl->arraydesc->dimension + 1;
1093 desc->elementtype = compvftbl->arraydesc->elementtype;
1096 desc->elementvftbl = compvftbl;
1097 desc->dimension = 1;
1098 desc->elementtype = ARRAYTYPE_OBJECT;
1102 /* c is an array of a primitive type */
1103 switch (c->name->text[1]) {
1105 desc->arraytype = ARRAYTYPE_BOOLEAN;
1106 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1107 desc->componentsize = sizeof(u1);
1111 desc->arraytype = ARRAYTYPE_BYTE;
1112 desc->dataoffset = OFFSET(java_bytearray_t,data);
1113 desc->componentsize = sizeof(u1);
1117 desc->arraytype = ARRAYTYPE_CHAR;
1118 desc->dataoffset = OFFSET(java_chararray_t,data);
1119 desc->componentsize = sizeof(u2);
1123 desc->arraytype = ARRAYTYPE_DOUBLE;
1124 desc->dataoffset = OFFSET(java_doublearray_t,data);
1125 desc->componentsize = sizeof(double);
1129 desc->arraytype = ARRAYTYPE_FLOAT;
1130 desc->dataoffset = OFFSET(java_floatarray_t,data);
1131 desc->componentsize = sizeof(float);
1135 desc->arraytype = ARRAYTYPE_INT;
1136 desc->dataoffset = OFFSET(java_intarray_t,data);
1137 desc->componentsize = sizeof(s4);
1141 desc->arraytype = ARRAYTYPE_LONG;
1142 desc->dataoffset = OFFSET(java_longarray_t,data);
1143 desc->componentsize = sizeof(s8);
1147 desc->arraytype = ARRAYTYPE_SHORT;
1148 desc->dataoffset = OFFSET(java_shortarray_t,data);
1149 desc->componentsize = sizeof(s2);
1153 exceptions_throw_noclassdeffounderror(c->name);
1157 desc->componentvftbl = NULL;
1158 desc->elementvftbl = NULL;
1159 desc->dimension = 1;
1160 desc->elementtype = desc->arraytype;
1167 /* linker_compute_subclasses ***************************************************
1171 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1172 This function needs to take the class renumber lock and stop the
1173 world during class renumbering. The lock is used in C code which
1174 is not that performance critical. Whereas JIT code uses critical
1175 sections to atomically access the class values.
1177 *******************************************************************************/
1179 static void linker_compute_subclasses(classinfo *c)
1182 if (!(c->flags & ACC_INTERFACE)) {
1185 c->vftbl->baseval = 1; /* so it does not look like an interface */
1188 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1189 c->nextsub = c->super->sub;
1198 /* linker_compute_class_values *************************************************
1202 *******************************************************************************/
1204 static void linker_compute_class_values(classinfo *c)
1208 c->vftbl->baseval = ++classvalue;
1213 linker_compute_class_values(subs);
1215 subs = subs->nextsub;
1218 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1222 /* linker_addinterface *********************************************************
1224 Is needed by link_class for adding a VTBL to a class. All
1225 interfaces implemented by ic are added as well.
1228 true.........everything ok
1229 false........an exception has been thrown
1231 *******************************************************************************/
1233 static bool linker_addinterface(classinfo *c, classinfo *ic)
1244 if (i >= v->interfacetablelength)
1245 vm_abort("Internal error: interfacetable overflow");
1247 /* if this interface has already been added, return immediately */
1249 if (v->interfacetable[-i] != NULL)
1252 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1253 v->interfacevftbllength[i] = 1;
1254 v->interfacetable[-i] = MNEW(methodptr, 1);
1255 v->interfacetable[-i][0] = NULL;
1258 v->interfacevftbllength[i] = ic->methodscount;
1259 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1261 #if defined(ENABLE_STATISTICS)
1263 count_vftbl_len += sizeof(methodptr) *
1264 (ic->methodscount + (ic->methodscount == 0));
1267 for (j = 0; j < ic->methodscount; j++) {
1268 for (sc = c; sc != NULL; sc = sc->super) {
1269 for (k = 0; k < sc->methodscount; k++) {
1270 m = &(sc->methods[k]);
1272 if (method_canoverwrite(m, &(ic->methods[j]))) {
1273 /* method m overwrites the (abstract) method */
1274 #if defined(ENABLE_VERIFIER)
1275 /* Add loading constraints (for the more
1276 general types of the method
1278 if (!classcache_add_constraints_for_params(
1279 c->classloader, ic->classloader,
1286 /* XXX taken from gcj */
1287 /* check for ACC_STATIC: IncompatibleClassChangeError */
1289 /* check for !ACC_PUBLIC: IllegalAccessError */
1291 /* check for ACC_ABSTRACT: AbstracMethodError,
1292 not sure about that one */
1294 v->interfacetable[-i][j] = v->table[m->vftblindex];
1300 /* If no method was found, insert the AbstractMethodError
1303 #if defined(ENABLE_JIT)
1304 # if defined(ENABLE_INTRP)
1306 v->interfacetable[-i][j] =
1307 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1310 v->interfacetable[-i][j] =
1311 (methodptr) (ptrint) &asm_abstractmethoderror;
1313 v->interfacetable[-i][j] =
1314 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1322 /* add superinterfaces of this interface */
1324 for (j = 0; j < ic->interfacescount; j++)
1325 if (!linker_addinterface(c, ic->interfaces[j]))
1334 /* class_highestinterface ******************************************************
1336 Used by the function link_class to determine the amount of memory
1337 needed for the interface table.
1339 *******************************************************************************/
1341 static s4 class_highestinterface(classinfo *c)
1347 /* check for ACC_INTERFACE bit already done in link_class_intern */
1351 for (i = 0; i < c->interfacescount; i++) {
1352 h2 = class_highestinterface(c->interfaces[i]);
1363 * These are local overrides for various environment variables in Emacs.
1364 * Please do not remove this and leave it at the end of the file, where
1365 * Emacs will automagically detect them.
1366 * ---------------------------------------------------------------------
1369 * indent-tabs-mode: t
1373 * vim:noexpandtab:sw=4:ts=4: