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.hpp"
37 #include "threads/lock.hpp"
38 #include "threads/mutex.hpp"
40 #include "toolbox/logging.h"
42 #include "vm/access.hpp"
43 #include "vm/array.hpp"
44 #include "vm/class.hpp"
45 #include "vm/classcache.hpp"
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.hpp" */
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 java_object_t *linker_classrenumber_lock;
101 #if defined(__cplusplus)
105 /* private functions **********************************************************/
107 static classinfo *link_class_intern(classinfo *c);
108 static arraydescriptor *link_array(classinfo *c);
109 static void linker_compute_class_values(classinfo *c);
110 static void linker_compute_subclasses(classinfo *c);
111 static bool linker_addinterface(classinfo *c, classinfo *ic);
112 static s4 class_highestinterface(classinfo *c);
115 /* linker_init *****************************************************************
117 Initializes the linker subsystem and links classes required for the
120 *******************************************************************************/
122 void linker_preinit(void)
124 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
126 /* Reset interface index. */
130 #if defined(ENABLE_THREADS) && !USES_NEW_SUBTYPE
131 /* create the global lock object */
133 linker_classrenumber_lock = NEW(java_object_t);
135 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
138 /* Link the most basic classes. */
140 if (!link_class(class_java_lang_Object))
141 vm_abort("linker_preinit: linking java/lang/Object failed");
143 #if defined(ENABLE_JAVASE)
144 if (!link_class(class_java_lang_Cloneable))
145 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
147 if (!link_class(class_java_io_Serializable))
148 vm_abort("linker_preinit: linking java/io/Serializable failed");
153 /* linker_init *****************************************************************
155 Links all classes required in the VM.
157 *******************************************************************************/
159 void linker_init(void)
161 TRACESUBSYSTEMINITIALIZATION("linker_init");
163 /* Link java.lang.Class as first class of the system, because we
164 need it's vftbl for all other classes so we can use a class as
167 if (!link_class(class_java_lang_Class))
168 vm_abort("linker_init: linking java/lang/Class failed");
170 /* Now set the header.vftbl of all classes which were created
171 before java.lang.Class was linked. */
173 class_postset_header_vftbl();
175 /* Link primitive-type wrapping classes. */
177 #if defined(ENABLE_JAVASE)
178 if (!link_class(class_java_lang_Void))
179 vm_abort("linker_init: linking failed");
182 if (!link_class(class_java_lang_Boolean))
183 vm_abort("linker_init: linking failed");
185 if (!link_class(class_java_lang_Byte))
186 vm_abort("linker_init: linking failed");
188 if (!link_class(class_java_lang_Character))
189 vm_abort("linker_init: linking failed");
191 if (!link_class(class_java_lang_Short))
192 vm_abort("linker_init: linking failed");
194 if (!link_class(class_java_lang_Integer))
195 vm_abort("linker_init: linking failed");
197 if (!link_class(class_java_lang_Long))
198 vm_abort("linker_init: linking failed");
200 if (!link_class(class_java_lang_Float))
201 vm_abort("linker_init: linking failed");
203 if (!link_class(class_java_lang_Double))
204 vm_abort("linker_init: linking failed");
206 /* Link important system classes. */
208 if (!link_class(class_java_lang_String))
209 vm_abort("linker_init: linking java/lang/String failed");
211 #if defined(ENABLE_JAVASE)
212 if (!link_class(class_java_lang_ClassLoader))
213 vm_abort("linker_init: linking failed");
215 if (!link_class(class_java_lang_SecurityManager))
216 vm_abort("linker_init: linking failed");
219 if (!link_class(class_java_lang_System))
220 vm_abort("linker_init: linking failed");
222 if (!link_class(class_java_lang_Thread))
223 vm_abort("linker_init: linking failed");
225 #if defined(ENABLE_JAVASE)
226 if (!link_class(class_java_lang_ThreadGroup))
227 vm_abort("linker_init: linking failed");
230 if (!link_class(class_java_lang_Throwable))
231 vm_abort("linker_init: linking failed");
233 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
234 if (!link_class(class_java_lang_VMSystem))
235 vm_abort("linker_init: linking failed");
237 if (!link_class(class_java_lang_VMThread))
238 vm_abort("linker_init: linking failed");
240 if (!link_class(class_java_lang_VMThrowable))
241 vm_abort("linker_init: linking failed");
244 /* Important system exceptions. */
246 if (!link_class(class_java_lang_Exception))
247 vm_abort("linker_init: linking failed");
249 if (!link_class(class_java_lang_ClassNotFoundException))
250 vm_abort("linker_init: linking failed");
252 if (!link_class(class_java_lang_RuntimeException))
253 vm_abort("linker_init: linking failed");
255 /* some classes which may be used more often */
257 #if defined(ENABLE_JAVASE)
258 if (!link_class(class_java_lang_StackTraceElement))
259 vm_abort("linker_init: linking failed");
261 if (!link_class(class_java_lang_reflect_Constructor))
262 vm_abort("linker_init: linking failed");
264 if (!link_class(class_java_lang_reflect_Field))
265 vm_abort("linker_init: linking failed");
267 if (!link_class(class_java_lang_reflect_Method))
268 vm_abort("linker_init: linking failed");
270 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
271 if (!link_class(class_java_lang_reflect_VMConstructor))
272 vm_abort("linker_init: linking failed");
274 if (!link_class(class_java_lang_reflect_VMField))
275 vm_abort("linker_init: linking failed");
277 if (!link_class(class_java_lang_reflect_VMMethod))
278 vm_abort("linker_init: linking failed");
281 if (!link_class(class_java_security_PrivilegedAction))
282 vm_abort("linker_init: linking failed");
284 if (!link_class(class_java_util_Vector))
285 vm_abort("linker_init: linking failed");
287 if (!link_class(class_java_util_HashMap))
288 vm_abort("linker_init: linking failed");
290 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
291 if (!link_class(class_sun_misc_Signal))
292 vm_abort("linker_init: linking failed");
294 if (!link_class(class_sun_reflect_MagicAccessorImpl))
295 vm_abort("linker_init: linking failed");
298 if (!link_class(arrayclass_java_lang_Object))
299 vm_abort("linker_init: linking failed");
303 /* create pseudo classes used by the typechecker */
305 /* pseudo class for Arraystubs (extends java.lang.Object) */
307 pseudo_class_Arraystub =
308 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
309 pseudo_class_Arraystub->state |= CLASS_LOADED;
310 pseudo_class_Arraystub->super = class_java_lang_Object;
312 #if defined(ENABLE_JAVASE)
314 pseudo_class_Arraystub->interfacescount = 2;
315 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
316 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
317 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
319 #elif defined(ENABLE_JAVAME_CLDC1_1)
321 pseudo_class_Arraystub->interfacescount = 0;
322 pseudo_class_Arraystub->interfaces = NULL;
325 # error unknown Java configuration
328 if (!classcache_store_unique(pseudo_class_Arraystub))
329 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
331 if (!link_class(pseudo_class_Arraystub))
332 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
334 /* pseudo class representing the null type */
336 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
337 pseudo_class_Null->state |= CLASS_LOADED;
338 pseudo_class_Null->super = class_java_lang_Object;
340 if (!classcache_store_unique(pseudo_class_Null))
341 vm_abort("linker_init: could not cache pseudo_class_Null");
343 if (!link_class(pseudo_class_Null))
344 vm_abort("linker_init: linking failed");
346 /* pseudo class representing new uninitialized objects */
348 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
349 pseudo_class_New->state |= CLASS_LOADED;
350 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
351 pseudo_class_New->super = class_java_lang_Object;
353 if (!classcache_store_unique(pseudo_class_New))
354 vm_abort("linker_init: could not cache pseudo_class_New");
356 /* Correct vftbl-entries (retarded loading and linking of class
357 java/lang/String). */
359 stringtable_update();
363 /* link_class ******************************************************************
365 Wrapper function for link_class_intern to ease monitor enter/exit
366 and exception handling.
368 *******************************************************************************/
370 classinfo *link_class(classinfo *c)
373 #if defined(ENABLE_RT_TIMING)
374 struct timespec time_start, time_end;
377 RT_TIMING_GET_TIME(time_start);
380 exceptions_throw_nullpointerexception();
384 LOCK_MONITOR_ENTER(c);
386 /* Maybe the class is currently linking or is already linked.*/
388 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
389 LOCK_MONITOR_EXIT(c);
394 #if defined(ENABLE_STATISTICS)
397 if (opt_getcompilingtime)
398 compilingtime_stop();
400 if (opt_getloadingtime)
404 /* call the internal function */
406 r = link_class_intern(c);
408 /* If return value is NULL, we had a problem and the class is not
412 c->state &= ~CLASS_LINKING;
414 #if defined(ENABLE_STATISTICS)
417 if (opt_getloadingtime)
420 if (opt_getcompilingtime)
421 compilingtime_start();
424 LOCK_MONITOR_EXIT(c);
426 RT_TIMING_GET_TIME(time_end);
428 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
434 /* linker_overwrite_method *****************************************************
436 Overwrite a method with another one, update method flags and check
440 mg................the general method being overwritten
441 ms................the overwriting (more specialized) method
442 wl................worklist where to add invalidated methods
445 true..............everything ok
446 false.............an exception has been thrown
448 *******************************************************************************/
450 static bool linker_overwrite_method(methodinfo *mg,
452 method_worklist **wl)
460 /* overriding a final method is illegal */
462 if (mg->flags & ACC_FINAL) {
463 exceptions_throw_verifyerror(mg, "Overriding final method");
467 /* method ms overwrites method mg */
469 #if defined(ENABLE_VERIFIER)
470 /* Add loading constraints (for the more general types of method mg). */
471 /* Not for <init>, as it is not invoked virtually. */
473 if ((ms->name != utf_init)
474 && !classcache_add_constraints_for_params(
475 cs->classloader, cg->classloader, mg))
481 /* inherit the vftbl index, and record the overwriting */
483 ms->vftblindex = mg->vftblindex;
486 /* update flags and check assumptions */
487 /* <init> methods are a special case, as they are never dispatched dynamically */
489 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
492 #if defined(ENABLE_TLH)
493 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
494 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
495 ms->clazz->name->text, ms->name->text);
496 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
500 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
501 /* this adds another implementation */
503 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
505 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
507 method_break_assumption_monomorphic(mg, wl);
510 /* this is the first implementation */
512 mg->flags |= ACC_METHOD_IMPLEMENTED;
514 INLINELOG( printf("becomes implemented: "); method_println(mg); );
519 } while (mg != NULL);
526 /* link_class_intern ***********************************************************
528 Tries to link a class. The function calculates the length in bytes
529 that an instance of this class requires as well as the VTBL for
530 methods and interface methods.
532 *******************************************************************************/
535 static int build_display_inner(classinfo *topc, classinfo *c, int i)
541 if (c->vftbl->arraydesc)
543 arraydescriptor *a = c->vftbl->arraydesc;
544 if (a->elementvftbl && a->elementvftbl->clazz->super)
546 classinfo *cls = a->elementvftbl->clazz->super;
548 for (n=0; n<a->dimension; n++)
549 cls = class_array_of(cls, true);
550 depth = build_display_inner(topc, cls, i+1);
553 if (a->componentvftbl && a->elementvftbl)
555 depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
559 depth = build_display_inner(topc, c->super, i+1);
561 if (depth >= DISPLAY_SIZE)
563 if (depth == DISPLAY_SIZE)
565 topc->vftbl->subtype_overflow = MNEW(vftbl_t *, i+1);
566 #if defined(ENABLE_STATISTICS)
568 count_vftbl_len += sizeof(void*) * (i+1);
571 topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
574 topc->vftbl->subtype_display[depth] = c->vftbl;
578 static void build_display(classinfo *c)
583 depth = build_display_inner(c, c, 0) - 1;
584 c->vftbl->subtype_depth = depth;
585 if (depth >= DISPLAY_SIZE)
587 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
591 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
592 for (i=depth+1; i<=DISPLAY_SIZE; i++)
593 c->vftbl->subtype_display[i] = NULL;
598 static classinfo *link_class_intern(classinfo *c)
600 classinfo *super; /* super class */
601 classinfo *tc; /* temporary class variable */
602 s4 supervftbllength; /* vftbllegnth of super class */
603 s4 vftbllength; /* vftbllength of current class */
604 s4 interfacetablelength; /* interface table length */
605 vftbl_t *v; /* vftbl of current class */
606 s4 i; /* interface/method/field counter */
607 arraydescriptor *arraydesc; /* descriptor for array classes */
608 method_worklist *worklist; /* worklist for recompilation */
609 #if defined(ENABLE_RT_TIMING)
610 struct timespec time_start, time_resolving, time_compute_vftbl,
611 time_abstract, time_compute_iftbl, time_fill_vftbl,
612 time_offsets, time_fill_iftbl, time_finalizer,
616 RT_TIMING_GET_TIME(time_start);
620 /* the class must be loaded */
622 /* XXX should this be a specific exception? */
623 assert(c->state & CLASS_LOADED);
625 /* This is check in link_class. */
627 assert(!(c->state & CLASS_LINKED));
629 /* cache the self-reference of this class */
630 /* we do this for cases where the defining loader of the class */
631 /* has not yet been recorded as an initiating loader for the class */
632 /* this is needed so subsequent code can assume that self-refs */
633 /* will always resolve lazily */
634 /* No need to do it for the bootloader - it is always registered */
635 /* as initiating loader for the classes it loads. */
637 classcache_store(c->classloader,c,false);
639 /* this class is currently linking */
641 c->state |= CLASS_LINKING;
646 /* Link the super interfaces. */
648 for (i = 0; i < c->interfacescount; i++) {
649 tc = c->interfaces[i];
651 if (!(tc->state & CLASS_LINKED))
656 /* check super class */
660 /* Check for java/lang/Object. */
662 if (c->super == NULL) {
664 c->instancesize = sizeof(java_object_t);
666 vftbllength = supervftbllength = 0;
671 /* Get super class. */
675 /* Link the super class if necessary. */
677 if (!(super->state & CLASS_LINKED))
678 if (!link_class(super))
681 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
684 c->flags |= (super->flags &
685 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
687 /* handle array classes */
689 if (c->name->text[0] == '[')
690 if (!(arraydesc = link_array(c)))
693 if (c->flags & ACC_INTERFACE)
694 c->index = interfaceindex++;
696 c->index = super->index + 1;
698 c->instancesize = super->instancesize;
700 vftbllength = supervftbllength = super->vftbl->vftbllength;
702 c->finalizer = super->finalizer;
704 RT_TIMING_GET_TIME(time_resolving);
707 /* compute vftbl length */
709 for (i = 0; i < c->methodscount; i++) {
710 methodinfo *m = &(c->methods[i]);
712 if (!(m->flags & ACC_STATIC)) { /* is instance method */
718 for (j = 0; j < tc->methodscount; j++) {
719 if (method_canoverwrite(m, &(tc->methods[j]))) {
720 if (tc->methods[j].flags & ACC_PRIVATE)
721 goto notfoundvftblindex;
723 /* package-private methods in other packages */
724 /* must not be overridden */
725 /* (see Java Language Specification 8.4.8.1) */
726 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
727 && !SAME_PACKAGE(c,tc) )
729 goto notfoundvftblindex;
732 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
735 goto foundvftblindex;
743 m->vftblindex = (vftbllength++);
748 RT_TIMING_GET_TIME(time_compute_vftbl);
751 /* Check all interfaces of an abstract class (maybe be an
752 interface too) for unimplemented methods. Such methods are
753 called miranda-methods and are marked with the ACC_MIRANDA
754 flag. VMClass.getDeclaredMethods does not return such
757 if (c->flags & ACC_ABSTRACT) {
760 s4 abstractmethodscount;
764 abstractmethodscount = 0;
766 /* check all interfaces of the abstract class */
768 for (i = 0; i < c->interfacescount; i++) {
769 ic = c->interfaces[i];
771 for (j = 0; j < ic->methodscount; j++) {
772 im = &(ic->methods[j]);
774 /* skip `<clinit>' and `<init>' */
776 if ((im->name == utf_clinit) || (im->name == utf_init))
779 for (tc = c; tc != NULL; tc = tc->super) {
780 for (k = 0; k < tc->methodscount; k++) {
781 if (method_canoverwrite(im, &(tc->methods[k])))
782 goto noabstractmethod;
786 abstractmethodscount++;
793 if (abstractmethodscount > 0) {
796 /* reallocate methods memory */
798 c->methods = (methodinfo*) MREALLOC(c->methods, methodinfo, c->methodscount,
799 c->methodscount + abstractmethodscount);
801 for (i = 0; i < c->interfacescount; i++) {
802 ic = c->interfaces[i];
804 for (j = 0; j < ic->methodscount; j++) {
805 im = &(ic->methods[j]);
807 /* skip `<clinit>' and `<init>' */
809 if ((im->name == utf_clinit) || (im->name == utf_init))
812 for (tc = c; tc != NULL; tc = tc->super) {
813 for (k = 0; k < tc->methodscount; k++) {
814 if (method_canoverwrite(im, &(tc->methods[k])))
815 goto noabstractmethod2;
819 /* Copy the method found into the new c->methods
820 array and tag it as miranda-method. */
822 am = &(c->methods[c->methodscount]);
825 MCOPY(am, im, methodinfo, 1);
827 am->vftblindex = (vftbllength++);
829 am->flags |= ACC_MIRANDA;
837 RT_TIMING_GET_TIME(time_abstract);
840 #if defined(ENABLE_STATISTICS)
843 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
846 /* compute interfacetable length */
848 interfacetablelength = 0;
850 for (tc = c; tc != NULL; tc = tc->super) {
851 for (i = 0; i < tc->interfacescount; i++) {
852 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
854 if (h > interfacetablelength)
855 interfacetablelength = h;
858 RT_TIMING_GET_TIME(time_compute_iftbl);
860 /* allocate virtual function table */
862 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
863 sizeof(methodptr) * (vftbllength - 1) +
864 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
865 v = (vftbl_t *) (((methodptr *) v) +
866 (interfacetablelength - 1) * (interfacetablelength > 1));
870 v->vftbllength = vftbllength;
871 v->interfacetablelength = interfacetablelength;
872 v->arraydesc = arraydesc;
874 /* store interface index in vftbl */
876 if (c->flags & ACC_INTERFACE)
877 v->baseval = -(c->index);
879 /* copy virtual function table of super class */
881 for (i = 0; i < supervftbllength; i++)
882 v->table[i] = super->vftbl->table[i];
884 /* Fill the remaining vftbl slots with the AbstractMethodError
885 stub (all after the super class slots, because they are already
888 for (; i < vftbllength; i++) {
889 #if defined(ENABLE_JIT)
890 # if defined(ENABLE_INTRP)
892 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
895 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
897 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
901 /* add method stubs into virtual function table */
903 for (i = 0; i < c->methodscount; i++) {
904 methodinfo *m = &(c->methods[i]);
906 assert(m->stubroutine == NULL);
908 /* Don't create a compiler stub for abstract methods as they
909 throw an AbstractMethodError with the default stub in the
910 vftbl. This entry is simply copied by sub-classes. */
912 if (m->flags & ACC_ABSTRACT)
915 #if defined(ENABLE_JIT)
916 # if defined(ENABLE_INTRP)
918 m->stubroutine = intrp_createcompilerstub(m);
921 m->stubroutine = (u1*) CompilerStub::generate(m);
923 m->stubroutine = intrp_createcompilerstub(m);
926 /* static methods are not in the vftbl */
928 if (m->flags & ACC_STATIC)
931 /* insert the stubroutine into the vftbl */
933 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
935 RT_TIMING_GET_TIME(time_fill_vftbl);
937 /* compute instance size and offset of each field */
939 for (i = 0; i < c->fieldscount; i++) {
941 fieldinfo *f = &(c->fields[i]);
943 if (!(f->flags & ACC_STATIC)) {
944 dsize = descriptor_typesize(f->parseddesc);
945 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
946 f->offset = c->instancesize;
947 c->instancesize += dsize;
950 RT_TIMING_GET_TIME(time_offsets);
952 /* initialize interfacetable and interfacevftbllength */
954 v->interfacevftbllength = MNEW(s4, interfacetablelength);
956 #if defined(ENABLE_STATISTICS)
958 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
961 for (i = 0; i < interfacetablelength; i++) {
962 v->interfacevftbllength[i] = 0;
963 v->interfacetable[-i] = NULL;
968 for (tc = c; tc != NULL; tc = tc->super)
969 for (i = 0; i < tc->interfacescount; i++)
970 if (!linker_addinterface(c, tc->interfaces[i]))
973 RT_TIMING_GET_TIME(time_fill_iftbl);
975 /* add finalizer method (not for java.lang.Object) */
980 fi = class_findmethod(c, utf_finalize, utf_void__void);
983 if (!(fi->flags & ACC_STATIC))
986 RT_TIMING_GET_TIME(time_finalizer);
990 linker_compute_subclasses(c);
992 /* FIXME: this is completely useless now */
993 RT_TIMING_GET_TIME(time_subclasses);
999 /* revert the linking state and class is linked */
1001 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
1003 /* check worklist */
1005 /* XXX must this also be done in case of exception? */
1007 while (worklist != NULL) {
1008 method_worklist *wi = worklist;
1010 worklist = worklist->next;
1012 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
1013 jit_invalidate_code(wi->m);
1015 /* XXX put worklist into dump memory? */
1016 FREE(wi, method_worklist);
1019 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1020 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1021 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1022 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1023 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1024 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1025 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1026 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1027 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1029 /* just return c to show that we didn't had a problem */
1035 /* link_array ******************************************************************
1037 This function is called by link_class to create the arraydescriptor
1040 This function returns NULL if the array cannot be linked because
1041 the component type has not been linked yet.
1043 *******************************************************************************/
1045 static arraydescriptor *link_array(classinfo *c)
1049 arraydescriptor *desc;
1054 namelen = c->name->blength;
1056 /* Check the component type */
1058 switch (c->name->text[1]) {
1060 /* c is an array of arrays. */
1061 u = utf_new(c->name->text + 1, namelen - 1);
1062 if (!(comp = load_class_from_classloader(u, c->classloader)))
1067 /* c is an array of objects. */
1068 u = utf_new(c->name->text + 2, namelen - 3);
1069 if (!(comp = load_class_from_classloader(u, c->classloader)))
1074 /* If the component type has not been linked, link it now */
1076 assert(!comp || (comp->state & CLASS_LOADED));
1078 if (comp && !(comp->state & CLASS_LINKED))
1079 if (!link_class(comp))
1082 /* Allocate the arraydescriptor */
1084 desc = NEW(arraydescriptor);
1087 /* c is an array of references */
1088 desc->arraytype = ARRAYTYPE_OBJECT;
1089 desc->componentsize = sizeof(void*);
1090 desc->dataoffset = OFFSET(java_objectarray_t, data);
1092 compvftbl = comp->vftbl;
1095 log_text("Component class has no vftbl");
1099 desc->componentvftbl = compvftbl;
1101 if (compvftbl->arraydesc) {
1102 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1104 if (compvftbl->arraydesc->dimension >= 255) {
1105 log_text("Creating array of dimension >255");
1109 desc->dimension = compvftbl->arraydesc->dimension + 1;
1110 desc->elementtype = compvftbl->arraydesc->elementtype;
1113 desc->elementvftbl = compvftbl;
1114 desc->dimension = 1;
1115 desc->elementtype = ARRAYTYPE_OBJECT;
1119 /* c is an array of a primitive type */
1120 switch (c->name->text[1]) {
1122 desc->arraytype = ARRAYTYPE_BOOLEAN;
1123 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1124 desc->componentsize = sizeof(u1);
1128 desc->arraytype = ARRAYTYPE_BYTE;
1129 desc->dataoffset = OFFSET(java_bytearray_t,data);
1130 desc->componentsize = sizeof(u1);
1134 desc->arraytype = ARRAYTYPE_CHAR;
1135 desc->dataoffset = OFFSET(java_chararray_t,data);
1136 desc->componentsize = sizeof(u2);
1140 desc->arraytype = ARRAYTYPE_DOUBLE;
1141 desc->dataoffset = OFFSET(java_doublearray_t,data);
1142 desc->componentsize = sizeof(double);
1146 desc->arraytype = ARRAYTYPE_FLOAT;
1147 desc->dataoffset = OFFSET(java_floatarray_t,data);
1148 desc->componentsize = sizeof(float);
1152 desc->arraytype = ARRAYTYPE_INT;
1153 desc->dataoffset = OFFSET(java_intarray_t,data);
1154 desc->componentsize = sizeof(s4);
1158 desc->arraytype = ARRAYTYPE_LONG;
1159 desc->dataoffset = OFFSET(java_longarray_t,data);
1160 desc->componentsize = sizeof(s8);
1164 desc->arraytype = ARRAYTYPE_SHORT;
1165 desc->dataoffset = OFFSET(java_shortarray_t,data);
1166 desc->componentsize = sizeof(s2);
1170 exceptions_throw_noclassdeffounderror(c->name);
1174 desc->componentvftbl = NULL;
1175 desc->elementvftbl = NULL;
1176 desc->dimension = 1;
1177 desc->elementtype = desc->arraytype;
1184 /* linker_compute_subclasses ***************************************************
1188 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1189 This function needs to take the class renumber lock and stop the
1190 world during class renumbering. The lock is used in C code which
1191 is not that performance critical. Whereas JIT code uses critical
1192 sections to atomically access the class values.
1194 *******************************************************************************/
1196 static void linker_compute_subclasses(classinfo *c)
1199 LOCK_CLASSRENUMBER_LOCK;
1201 if (!(c->flags & ACC_INTERFACE)) {
1204 #if USES_NEW_SUBTYPE
1205 c->vftbl->baseval = 1; /* so it does not look like an interface */
1209 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1210 c->nextsub = c->super->sub;
1216 #if !USES_NEW_SUBTYPE
1217 /* compute class values */
1219 linker_compute_class_values(class_java_lang_Object);
1222 UNLOCK_CLASSRENUMBER_LOCK;
1227 /* linker_compute_class_values *************************************************
1231 *******************************************************************************/
1233 static void linker_compute_class_values(classinfo *c)
1237 c->vftbl->baseval = ++classvalue;
1242 linker_compute_class_values(subs);
1244 subs = subs->nextsub;
1247 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1251 /* linker_addinterface *********************************************************
1253 Is needed by link_class for adding a VTBL to a class. All
1254 interfaces implemented by ic are added as well.
1257 true.........everything ok
1258 false........an exception has been thrown
1260 *******************************************************************************/
1262 static bool linker_addinterface(classinfo *c, classinfo *ic)
1273 if (i >= v->interfacetablelength)
1274 vm_abort("Internal error: interfacetable overflow");
1276 /* if this interface has already been added, return immediately */
1278 if (v->interfacetable[-i] != NULL)
1281 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1282 v->interfacevftbllength[i] = 1;
1283 v->interfacetable[-i] = MNEW(methodptr, 1);
1284 v->interfacetable[-i][0] = NULL;
1287 v->interfacevftbllength[i] = ic->methodscount;
1288 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1290 #if defined(ENABLE_STATISTICS)
1292 count_vftbl_len += sizeof(methodptr) *
1293 (ic->methodscount + (ic->methodscount == 0));
1296 for (j = 0; j < ic->methodscount; j++) {
1297 for (sc = c; sc != NULL; sc = sc->super) {
1298 for (k = 0; k < sc->methodscount; k++) {
1299 m = &(sc->methods[k]);
1301 if (method_canoverwrite(m, &(ic->methods[j]))) {
1302 /* method m overwrites the (abstract) method */
1303 #if defined(ENABLE_VERIFIER)
1304 /* Add loading constraints (for the more
1305 general types of the method
1307 if (!classcache_add_constraints_for_params(
1308 c->classloader, ic->classloader,
1315 /* XXX taken from gcj */
1316 /* check for ACC_STATIC: IncompatibleClassChangeError */
1318 /* check for !ACC_PUBLIC: IllegalAccessError */
1320 /* check for ACC_ABSTRACT: AbstracMethodError,
1321 not sure about that one */
1323 v->interfacetable[-i][j] = v->table[m->vftblindex];
1329 /* If no method was found, insert the AbstractMethodError
1332 #if defined(ENABLE_JIT)
1333 # if defined(ENABLE_INTRP)
1335 v->interfacetable[-i][j] =
1336 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1339 v->interfacetable[-i][j] =
1340 (methodptr) (ptrint) &asm_abstractmethoderror;
1342 v->interfacetable[-i][j] =
1343 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1351 /* add superinterfaces of this interface */
1353 for (j = 0; j < ic->interfacescount; j++)
1354 if (!linker_addinterface(c, ic->interfaces[j]))
1363 /* class_highestinterface ******************************************************
1365 Used by the function link_class to determine the amount of memory
1366 needed for the interface table.
1368 *******************************************************************************/
1370 static s4 class_highestinterface(classinfo *c)
1376 /* check for ACC_INTERFACE bit already done in link_class_intern */
1380 for (i = 0; i < c->interfacescount; i++) {
1381 h2 = class_highestinterface(c->interfaces[i]);
1390 #if defined(__cplusplus)
1395 * These are local overrides for various environment variables in Emacs.
1396 * Please do not remove this and leave it at the end of the file, where
1397 * Emacs will automagically detect them.
1398 * ---------------------------------------------------------------------
1401 * indent-tabs-mode: t
1405 * vim:noexpandtab:sw=4:ts=4: