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 */
97 #if defined(__cplusplus)
101 /* private functions **********************************************************/
103 static classinfo *link_class_intern(classinfo *c);
104 static arraydescriptor *link_array(classinfo *c);
105 static void linker_compute_class_values(classinfo *c);
106 static void linker_compute_subclasses(classinfo *c);
107 static bool linker_addinterface(classinfo *c, classinfo *ic);
108 static s4 class_highestinterface(classinfo *c);
111 /* linker_init *****************************************************************
113 Initializes the linker subsystem and links classes required for the
116 *******************************************************************************/
118 void linker_preinit(void)
120 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
122 /* Reset interface index. */
126 /* Link the most basic classes. */
128 if (!link_class(class_java_lang_Object))
129 vm_abort("linker_preinit: linking java/lang/Object failed");
131 #if defined(ENABLE_JAVASE)
132 if (!link_class(class_java_lang_Cloneable))
133 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
135 if (!link_class(class_java_io_Serializable))
136 vm_abort("linker_preinit: linking java/io/Serializable failed");
141 /* linker_init *****************************************************************
143 Links all classes required in the VM.
145 *******************************************************************************/
147 void linker_init(void)
149 TRACESUBSYSTEMINITIALIZATION("linker_init");
151 /* Link java.lang.Class as first class of the system, because we
152 need it's vftbl for all other classes so we can use a class as
155 if (!link_class(class_java_lang_Class))
156 vm_abort("linker_init: linking java/lang/Class failed");
158 /* Now set the header.vftbl of all classes which were created
159 before java.lang.Class was linked. */
161 class_postset_header_vftbl();
163 /* Link primitive-type wrapping classes. */
165 #if defined(ENABLE_JAVASE)
166 if (!link_class(class_java_lang_Void))
167 vm_abort("linker_init: linking failed");
170 if (!link_class(class_java_lang_Boolean))
171 vm_abort("linker_init: linking failed");
173 if (!link_class(class_java_lang_Byte))
174 vm_abort("linker_init: linking failed");
176 if (!link_class(class_java_lang_Character))
177 vm_abort("linker_init: linking failed");
179 if (!link_class(class_java_lang_Short))
180 vm_abort("linker_init: linking failed");
182 if (!link_class(class_java_lang_Integer))
183 vm_abort("linker_init: linking failed");
185 if (!link_class(class_java_lang_Long))
186 vm_abort("linker_init: linking failed");
188 if (!link_class(class_java_lang_Float))
189 vm_abort("linker_init: linking failed");
191 if (!link_class(class_java_lang_Double))
192 vm_abort("linker_init: linking failed");
194 /* Link important system classes. */
196 if (!link_class(class_java_lang_String))
197 vm_abort("linker_init: linking java/lang/String failed");
199 #if defined(ENABLE_JAVASE)
200 if (!link_class(class_java_lang_ClassLoader))
201 vm_abort("linker_init: linking failed");
203 if (!link_class(class_java_lang_SecurityManager))
204 vm_abort("linker_init: linking failed");
207 if (!link_class(class_java_lang_System))
208 vm_abort("linker_init: linking failed");
210 if (!link_class(class_java_lang_Thread))
211 vm_abort("linker_init: linking failed");
213 #if defined(ENABLE_JAVASE)
214 if (!link_class(class_java_lang_ThreadGroup))
215 vm_abort("linker_init: linking failed");
218 if (!link_class(class_java_lang_Throwable))
219 vm_abort("linker_init: linking failed");
221 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
222 if (!link_class(class_java_lang_VMSystem))
223 vm_abort("linker_init: linking failed");
225 if (!link_class(class_java_lang_VMThread))
226 vm_abort("linker_init: linking failed");
228 if (!link_class(class_java_lang_VMThrowable))
229 vm_abort("linker_init: linking failed");
232 /* Important system exceptions. */
234 if (!link_class(class_java_lang_Exception))
235 vm_abort("linker_init: linking failed");
237 if (!link_class(class_java_lang_ClassNotFoundException))
238 vm_abort("linker_init: linking failed");
240 if (!link_class(class_java_lang_RuntimeException))
241 vm_abort("linker_init: linking failed");
243 /* some classes which may be used more often */
245 #if defined(ENABLE_JAVASE)
246 if (!link_class(class_java_lang_StackTraceElement))
247 vm_abort("linker_init: linking failed");
249 if (!link_class(class_java_lang_reflect_Constructor))
250 vm_abort("linker_init: linking failed");
252 if (!link_class(class_java_lang_reflect_Field))
253 vm_abort("linker_init: linking failed");
255 if (!link_class(class_java_lang_reflect_Method))
256 vm_abort("linker_init: linking failed");
258 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
259 if (!link_class(class_java_lang_reflect_VMConstructor))
260 vm_abort("linker_init: linking failed");
262 if (!link_class(class_java_lang_reflect_VMField))
263 vm_abort("linker_init: linking failed");
265 if (!link_class(class_java_lang_reflect_VMMethod))
266 vm_abort("linker_init: linking failed");
269 if (!link_class(class_java_security_PrivilegedAction))
270 vm_abort("linker_init: linking failed");
272 if (!link_class(class_java_util_Vector))
273 vm_abort("linker_init: linking failed");
275 if (!link_class(class_java_util_HashMap))
276 vm_abort("linker_init: linking failed");
278 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
279 if (!link_class(class_sun_misc_Signal))
280 vm_abort("linker_init: linking failed");
282 if (!link_class(class_sun_reflect_MagicAccessorImpl))
283 vm_abort("linker_init: linking failed");
286 if (!link_class(arrayclass_java_lang_Object))
287 vm_abort("linker_init: linking failed");
291 /* create pseudo classes used by the typechecker */
293 /* pseudo class for Arraystubs (extends java.lang.Object) */
295 pseudo_class_Arraystub =
296 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
297 pseudo_class_Arraystub->state |= CLASS_LOADED;
298 pseudo_class_Arraystub->super = class_java_lang_Object;
300 #if defined(ENABLE_JAVASE)
302 pseudo_class_Arraystub->interfacescount = 2;
303 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
304 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
305 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
307 #elif defined(ENABLE_JAVAME_CLDC1_1)
309 pseudo_class_Arraystub->interfacescount = 0;
310 pseudo_class_Arraystub->interfaces = NULL;
313 # error unknown Java configuration
316 if (!classcache_store_unique(pseudo_class_Arraystub))
317 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
319 if (!link_class(pseudo_class_Arraystub))
320 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
322 /* pseudo class representing the null type */
324 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
325 pseudo_class_Null->state |= CLASS_LOADED;
326 pseudo_class_Null->super = class_java_lang_Object;
328 if (!classcache_store_unique(pseudo_class_Null))
329 vm_abort("linker_init: could not cache pseudo_class_Null");
331 if (!link_class(pseudo_class_Null))
332 vm_abort("linker_init: linking failed");
334 /* pseudo class representing new uninitialized objects */
336 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
337 pseudo_class_New->state |= CLASS_LOADED;
338 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
339 pseudo_class_New->super = class_java_lang_Object;
341 if (!classcache_store_unique(pseudo_class_New))
342 vm_abort("linker_init: could not cache pseudo_class_New");
344 /* Correct vftbl-entries (retarded loading and linking of class
345 java/lang/String). */
347 stringtable_update();
351 /* link_class ******************************************************************
353 Wrapper function for link_class_intern to ease monitor enter/exit
354 and exception handling.
356 *******************************************************************************/
358 classinfo *link_class(classinfo *c)
361 #if defined(ENABLE_RT_TIMING)
362 struct timespec time_start, time_end;
365 RT_TIMING_GET_TIME(time_start);
368 exceptions_throw_nullpointerexception();
372 LOCK_MONITOR_ENTER(c);
374 /* Maybe the class is currently linking or is already linked.*/
376 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
377 LOCK_MONITOR_EXIT(c);
382 #if defined(ENABLE_STATISTICS)
385 if (opt_getcompilingtime)
386 compilingtime_stop();
388 if (opt_getloadingtime)
392 /* call the internal function */
394 r = link_class_intern(c);
396 /* If return value is NULL, we had a problem and the class is not
400 c->state &= ~CLASS_LINKING;
402 #if defined(ENABLE_STATISTICS)
405 if (opt_getloadingtime)
408 if (opt_getcompilingtime)
409 compilingtime_start();
412 LOCK_MONITOR_EXIT(c);
414 RT_TIMING_GET_TIME(time_end);
416 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
422 /* linker_overwrite_method *****************************************************
424 Overwrite a method with another one, update method flags and check
428 mg................the general method being overwritten
429 ms................the overwriting (more specialized) method
430 wl................worklist where to add invalidated methods
433 true..............everything ok
434 false.............an exception has been thrown
436 *******************************************************************************/
438 static bool linker_overwrite_method(methodinfo *mg,
440 method_worklist **wl)
448 /* overriding a final method is illegal */
450 if (mg->flags & ACC_FINAL) {
451 exceptions_throw_verifyerror(mg, "Overriding final method");
455 /* method ms overwrites method mg */
457 #if defined(ENABLE_VERIFIER)
458 /* Add loading constraints (for the more general types of method mg). */
459 /* Not for <init>, as it is not invoked virtually. */
461 if ((ms->name != utf_init)
462 && !classcache_add_constraints_for_params(
463 cs->classloader, cg->classloader, mg))
469 /* inherit the vftbl index, and record the overwriting */
471 ms->vftblindex = mg->vftblindex;
474 /* update flags and check assumptions */
475 /* <init> methods are a special case, as they are never dispatched dynamically */
477 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
480 #if defined(ENABLE_TLH)
481 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
482 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
483 ms->clazz->name->text, ms->name->text);
484 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
488 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
489 /* this adds another implementation */
491 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
493 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
495 method_break_assumption_monomorphic(mg, wl);
498 /* this is the first implementation */
500 mg->flags |= ACC_METHOD_IMPLEMENTED;
502 INLINELOG( printf("becomes implemented: "); method_println(mg); );
507 } while (mg != NULL);
514 /* link_class_intern ***********************************************************
516 Tries to link a class. The function calculates the length in bytes
517 that an instance of this class requires as well as the VTBL for
518 methods and interface methods.
520 *******************************************************************************/
522 static int build_display_inner(classinfo *topc, classinfo *c, int i)
528 if (c->vftbl->arraydesc)
530 arraydescriptor *a = c->vftbl->arraydesc;
531 if (a->elementvftbl && a->elementvftbl->clazz->super)
533 classinfo *cls = a->elementvftbl->clazz->super;
535 for (n=0; n<a->dimension; n++)
536 cls = class_array_of(cls, true);
537 depth = build_display_inner(topc, cls, i+1);
540 if (a->componentvftbl && a->elementvftbl)
542 depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
546 depth = build_display_inner(topc, c->super, i+1);
548 if (depth >= DISPLAY_SIZE)
550 if (depth == DISPLAY_SIZE)
552 topc->vftbl->subtype_overflow = MNEW(vftbl_t *, i+1);
553 #if defined(ENABLE_STATISTICS)
555 count_vftbl_len += sizeof(void*) * (i+1);
558 topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
561 topc->vftbl->subtype_display[depth] = c->vftbl;
565 static void build_display(classinfo *c)
570 depth = build_display_inner(c, c, 0) - 1;
571 c->vftbl->subtype_depth = depth;
572 if (depth >= DISPLAY_SIZE)
574 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
578 c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
579 for (i=depth+1; i<=DISPLAY_SIZE; i++)
580 c->vftbl->subtype_display[i] = NULL;
584 static classinfo *link_class_intern(classinfo *c)
586 classinfo *super; /* super class */
587 classinfo *tc; /* temporary class variable */
588 s4 supervftbllength; /* vftbllegnth of super class */
589 s4 vftbllength; /* vftbllength of current class */
590 s4 interfacetablelength; /* interface table length */
591 vftbl_t *v; /* vftbl of current class */
592 s4 i; /* interface/method/field counter */
593 arraydescriptor *arraydesc; /* descriptor for array classes */
594 method_worklist *worklist; /* worklist for recompilation */
595 #if defined(ENABLE_RT_TIMING)
596 struct timespec time_start, time_resolving, time_compute_vftbl,
597 time_abstract, time_compute_iftbl, time_fill_vftbl,
598 time_offsets, time_fill_iftbl, time_finalizer,
602 RT_TIMING_GET_TIME(time_start);
606 /* the class must be loaded */
608 /* XXX should this be a specific exception? */
609 assert(c->state & CLASS_LOADED);
611 /* This is check in link_class. */
613 assert(!(c->state & CLASS_LINKED));
615 /* cache the self-reference of this class */
616 /* we do this for cases where the defining loader of the class */
617 /* has not yet been recorded as an initiating loader for the class */
618 /* this is needed so subsequent code can assume that self-refs */
619 /* will always resolve lazily */
620 /* No need to do it for the bootloader - it is always registered */
621 /* as initiating loader for the classes it loads. */
623 classcache_store(c->classloader,c,false);
625 /* this class is currently linking */
627 c->state |= CLASS_LINKING;
632 /* Link the super interfaces. */
634 for (i = 0; i < c->interfacescount; i++) {
635 tc = c->interfaces[i];
637 if (!(tc->state & CLASS_LINKED))
642 /* check super class */
646 /* Check for java/lang/Object. */
648 if (c->super == NULL) {
650 c->instancesize = sizeof(java_object_t);
652 vftbllength = supervftbllength = 0;
657 /* Get super class. */
661 /* Link the super class if necessary. */
663 if (!(super->state & CLASS_LINKED))
664 if (!link_class(super))
667 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
670 c->flags |= (super->flags &
671 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
673 /* handle array classes */
675 if (c->name->text[0] == '[')
676 if (!(arraydesc = link_array(c)))
679 if (c->flags & ACC_INTERFACE)
680 c->index = interfaceindex++;
682 c->index = super->index + 1;
684 c->instancesize = super->instancesize;
686 vftbllength = supervftbllength = super->vftbl->vftbllength;
688 c->finalizer = super->finalizer;
690 RT_TIMING_GET_TIME(time_resolving);
693 /* compute vftbl length */
695 for (i = 0; i < c->methodscount; i++) {
696 methodinfo *m = &(c->methods[i]);
698 if (!(m->flags & ACC_STATIC)) { /* is instance method */
704 for (j = 0; j < tc->methodscount; j++) {
705 if (method_canoverwrite(m, &(tc->methods[j]))) {
706 if (tc->methods[j].flags & ACC_PRIVATE)
707 goto notfoundvftblindex;
709 /* package-private methods in other packages */
710 /* must not be overridden */
711 /* (see Java Language Specification 8.4.8.1) */
712 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
713 && !SAME_PACKAGE(c,tc) )
715 goto notfoundvftblindex;
718 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
721 goto foundvftblindex;
729 m->vftblindex = (vftbllength++);
734 RT_TIMING_GET_TIME(time_compute_vftbl);
737 /* Check all interfaces of an abstract class (maybe be an
738 interface too) for unimplemented methods. Such methods are
739 called miranda-methods and are marked with the ACC_MIRANDA
740 flag. VMClass.getDeclaredMethods does not return such
743 if (c->flags & ACC_ABSTRACT) {
746 s4 abstractmethodscount;
750 abstractmethodscount = 0;
752 /* check all interfaces of the abstract class */
754 for (i = 0; i < c->interfacescount; i++) {
755 ic = c->interfaces[i];
757 for (j = 0; j < ic->methodscount; j++) {
758 im = &(ic->methods[j]);
760 /* skip `<clinit>' and `<init>' */
762 if ((im->name == utf_clinit) || (im->name == utf_init))
765 for (tc = c; tc != NULL; tc = tc->super) {
766 for (k = 0; k < tc->methodscount; k++) {
767 if (method_canoverwrite(im, &(tc->methods[k])))
768 goto noabstractmethod;
772 abstractmethodscount++;
779 if (abstractmethodscount > 0) {
782 /* reallocate methods memory */
784 c->methods = (methodinfo*) MREALLOC(c->methods, methodinfo, c->methodscount,
785 c->methodscount + abstractmethodscount);
787 for (i = 0; i < c->interfacescount; i++) {
788 ic = c->interfaces[i];
790 for (j = 0; j < ic->methodscount; j++) {
791 im = &(ic->methods[j]);
793 /* skip `<clinit>' and `<init>' */
795 if ((im->name == utf_clinit) || (im->name == utf_init))
798 for (tc = c; tc != NULL; tc = tc->super) {
799 for (k = 0; k < tc->methodscount; k++) {
800 if (method_canoverwrite(im, &(tc->methods[k])))
801 goto noabstractmethod2;
805 /* Copy the method found into the new c->methods
806 array and tag it as miranda-method. */
808 am = &(c->methods[c->methodscount]);
811 MCOPY(am, im, methodinfo, 1);
813 am->vftblindex = (vftbllength++);
815 am->flags |= ACC_MIRANDA;
823 RT_TIMING_GET_TIME(time_abstract);
826 #if defined(ENABLE_STATISTICS)
829 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
832 /* compute interfacetable length */
834 interfacetablelength = 0;
836 for (tc = c; tc != NULL; tc = tc->super) {
837 for (i = 0; i < tc->interfacescount; i++) {
838 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
840 if (h > interfacetablelength)
841 interfacetablelength = h;
844 RT_TIMING_GET_TIME(time_compute_iftbl);
846 /* allocate virtual function table */
848 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
849 sizeof(methodptr) * (vftbllength - 1) +
850 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
851 v = (vftbl_t *) (((methodptr *) v) +
852 (interfacetablelength - 1) * (interfacetablelength > 1));
856 v->vftbllength = vftbllength;
857 v->interfacetablelength = interfacetablelength;
858 v->arraydesc = arraydesc;
860 /* store interface index in vftbl */
862 if (c->flags & ACC_INTERFACE)
863 v->baseval = -(c->index);
865 /* copy virtual function table of super class */
867 for (i = 0; i < supervftbllength; i++)
868 v->table[i] = super->vftbl->table[i];
870 /* Fill the remaining vftbl slots with the AbstractMethodError
871 stub (all after the super class slots, because they are already
874 for (; i < vftbllength; i++) {
875 #if defined(ENABLE_JIT)
876 # if defined(ENABLE_INTRP)
878 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
881 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
883 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
887 /* add method stubs into virtual function table */
889 for (i = 0; i < c->methodscount; i++) {
890 methodinfo *m = &(c->methods[i]);
892 assert(m->stubroutine == NULL);
894 /* Don't create a compiler stub for abstract methods as they
895 throw an AbstractMethodError with the default stub in the
896 vftbl. This entry is simply copied by sub-classes. */
898 if (m->flags & ACC_ABSTRACT)
901 #if defined(ENABLE_JIT)
902 # if defined(ENABLE_INTRP)
904 m->stubroutine = intrp_createcompilerstub(m);
907 m->stubroutine = (u1*) CompilerStub::generate(m);
909 m->stubroutine = intrp_createcompilerstub(m);
912 /* static methods are not in the vftbl */
914 if (m->flags & ACC_STATIC)
917 /* insert the stubroutine into the vftbl */
919 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
921 RT_TIMING_GET_TIME(time_fill_vftbl);
923 /* compute instance size and offset of each field */
925 for (i = 0; i < c->fieldscount; i++) {
927 fieldinfo *f = &(c->fields[i]);
929 if (!(f->flags & ACC_STATIC)) {
930 dsize = descriptor_typesize(f->parseddesc);
931 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
932 f->offset = c->instancesize;
933 c->instancesize += dsize;
936 RT_TIMING_GET_TIME(time_offsets);
938 /* initialize interfacetable and interfacevftbllength */
940 v->interfacevftbllength = MNEW(s4, interfacetablelength);
942 #if defined(ENABLE_STATISTICS)
944 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
947 for (i = 0; i < interfacetablelength; i++) {
948 v->interfacevftbllength[i] = 0;
949 v->interfacetable[-i] = NULL;
954 for (tc = c; tc != NULL; tc = tc->super)
955 for (i = 0; i < tc->interfacescount; i++)
956 if (!linker_addinterface(c, tc->interfaces[i]))
959 RT_TIMING_GET_TIME(time_fill_iftbl);
961 /* add finalizer method (not for java.lang.Object) */
966 fi = class_findmethod(c, utf_finalize, utf_void__void);
969 if (!(fi->flags & ACC_STATIC))
972 RT_TIMING_GET_TIME(time_finalizer);
976 linker_compute_subclasses(c);
978 /* FIXME: this is completely useless now */
979 RT_TIMING_GET_TIME(time_subclasses);
983 /* revert the linking state and class is linked */
985 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
989 /* XXX must this also be done in case of exception? */
991 while (worklist != NULL) {
992 method_worklist *wi = worklist;
994 worklist = worklist->next;
996 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
997 jit_invalidate_code(wi->m);
999 /* XXX put worklist into dump memory? */
1000 FREE(wi, method_worklist);
1003 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1004 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1005 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1006 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1007 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1008 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1009 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1010 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1011 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1013 /* just return c to show that we didn't had a problem */
1019 /* link_array ******************************************************************
1021 This function is called by link_class to create the arraydescriptor
1024 This function returns NULL if the array cannot be linked because
1025 the component type has not been linked yet.
1027 *******************************************************************************/
1029 static arraydescriptor *link_array(classinfo *c)
1033 arraydescriptor *desc;
1038 namelen = c->name->blength;
1040 /* Check the component type */
1042 switch (c->name->text[1]) {
1044 /* c is an array of arrays. */
1045 u = utf_new(c->name->text + 1, namelen - 1);
1046 if (!(comp = load_class_from_classloader(u, c->classloader)))
1051 /* c is an array of objects. */
1052 u = utf_new(c->name->text + 2, namelen - 3);
1053 if (!(comp = load_class_from_classloader(u, c->classloader)))
1058 /* If the component type has not been linked, link it now */
1060 assert(!comp || (comp->state & CLASS_LOADED));
1062 if (comp && !(comp->state & CLASS_LINKED))
1063 if (!link_class(comp))
1066 /* Allocate the arraydescriptor */
1068 desc = NEW(arraydescriptor);
1071 /* c is an array of references */
1072 desc->arraytype = ARRAYTYPE_OBJECT;
1073 desc->componentsize = sizeof(void*);
1074 desc->dataoffset = OFFSET(java_objectarray_t, data);
1076 compvftbl = comp->vftbl;
1079 log_text("Component class has no vftbl");
1083 desc->componentvftbl = compvftbl;
1085 if (compvftbl->arraydesc) {
1086 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1088 if (compvftbl->arraydesc->dimension >= 255) {
1089 log_text("Creating array of dimension >255");
1093 desc->dimension = compvftbl->arraydesc->dimension + 1;
1094 desc->elementtype = compvftbl->arraydesc->elementtype;
1097 desc->elementvftbl = compvftbl;
1098 desc->dimension = 1;
1099 desc->elementtype = ARRAYTYPE_OBJECT;
1103 /* c is an array of a primitive type */
1104 switch (c->name->text[1]) {
1106 desc->arraytype = ARRAYTYPE_BOOLEAN;
1107 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1108 desc->componentsize = sizeof(u1);
1112 desc->arraytype = ARRAYTYPE_BYTE;
1113 desc->dataoffset = OFFSET(java_bytearray_t,data);
1114 desc->componentsize = sizeof(u1);
1118 desc->arraytype = ARRAYTYPE_CHAR;
1119 desc->dataoffset = OFFSET(java_chararray_t,data);
1120 desc->componentsize = sizeof(u2);
1124 desc->arraytype = ARRAYTYPE_DOUBLE;
1125 desc->dataoffset = OFFSET(java_doublearray_t,data);
1126 desc->componentsize = sizeof(double);
1130 desc->arraytype = ARRAYTYPE_FLOAT;
1131 desc->dataoffset = OFFSET(java_floatarray_t,data);
1132 desc->componentsize = sizeof(float);
1136 desc->arraytype = ARRAYTYPE_INT;
1137 desc->dataoffset = OFFSET(java_intarray_t,data);
1138 desc->componentsize = sizeof(s4);
1142 desc->arraytype = ARRAYTYPE_LONG;
1143 desc->dataoffset = OFFSET(java_longarray_t,data);
1144 desc->componentsize = sizeof(s8);
1148 desc->arraytype = ARRAYTYPE_SHORT;
1149 desc->dataoffset = OFFSET(java_shortarray_t,data);
1150 desc->componentsize = sizeof(s2);
1154 exceptions_throw_noclassdeffounderror(c->name);
1158 desc->componentvftbl = NULL;
1159 desc->elementvftbl = NULL;
1160 desc->dimension = 1;
1161 desc->elementtype = desc->arraytype;
1168 /* linker_compute_subclasses ***************************************************
1172 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1173 This function needs to take the class renumber lock and stop the
1174 world during class renumbering. The lock is used in C code which
1175 is not that performance critical. Whereas JIT code uses critical
1176 sections to atomically access the class values.
1178 *******************************************************************************/
1180 static void linker_compute_subclasses(classinfo *c)
1183 if (!(c->flags & ACC_INTERFACE)) {
1186 c->vftbl->baseval = 1; /* so it does not look like an interface */
1189 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1190 c->nextsub = c->super->sub;
1199 /* linker_compute_class_values *************************************************
1203 *******************************************************************************/
1205 static void linker_compute_class_values(classinfo *c)
1209 c->vftbl->baseval = ++classvalue;
1214 linker_compute_class_values(subs);
1216 subs = subs->nextsub;
1219 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1223 /* linker_addinterface *********************************************************
1225 Is needed by link_class for adding a VTBL to a class. All
1226 interfaces implemented by ic are added as well.
1229 true.........everything ok
1230 false........an exception has been thrown
1232 *******************************************************************************/
1234 static bool linker_addinterface(classinfo *c, classinfo *ic)
1245 if (i >= v->interfacetablelength)
1246 vm_abort("Internal error: interfacetable overflow");
1248 /* if this interface has already been added, return immediately */
1250 if (v->interfacetable[-i] != NULL)
1253 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1254 v->interfacevftbllength[i] = 1;
1255 v->interfacetable[-i] = MNEW(methodptr, 1);
1256 v->interfacetable[-i][0] = NULL;
1259 v->interfacevftbllength[i] = ic->methodscount;
1260 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1262 #if defined(ENABLE_STATISTICS)
1264 count_vftbl_len += sizeof(methodptr) *
1265 (ic->methodscount + (ic->methodscount == 0));
1268 for (j = 0; j < ic->methodscount; j++) {
1269 for (sc = c; sc != NULL; sc = sc->super) {
1270 for (k = 0; k < sc->methodscount; k++) {
1271 m = &(sc->methods[k]);
1273 if (method_canoverwrite(m, &(ic->methods[j]))) {
1274 /* method m overwrites the (abstract) method */
1275 #if defined(ENABLE_VERIFIER)
1276 /* Add loading constraints (for the more
1277 general types of the method
1279 if (!classcache_add_constraints_for_params(
1280 c->classloader, ic->classloader,
1287 /* XXX taken from gcj */
1288 /* check for ACC_STATIC: IncompatibleClassChangeError */
1290 /* check for !ACC_PUBLIC: IllegalAccessError */
1292 /* check for ACC_ABSTRACT: AbstracMethodError,
1293 not sure about that one */
1295 v->interfacetable[-i][j] = v->table[m->vftblindex];
1301 /* If no method was found, insert the AbstractMethodError
1304 #if defined(ENABLE_JIT)
1305 # if defined(ENABLE_INTRP)
1307 v->interfacetable[-i][j] =
1308 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1311 v->interfacetable[-i][j] =
1312 (methodptr) (ptrint) &asm_abstractmethoderror;
1314 v->interfacetable[-i][j] =
1315 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1323 /* add superinterfaces of this interface */
1325 for (j = 0; j < ic->interfacescount; j++)
1326 if (!linker_addinterface(c, ic->interfaces[j]))
1335 /* class_highestinterface ******************************************************
1337 Used by the function link_class to determine the amount of memory
1338 needed for the interface table.
1340 *******************************************************************************/
1342 static s4 class_highestinterface(classinfo *c)
1348 /* check for ACC_INTERFACE bit already done in link_class_intern */
1352 for (i = 0; i < c->interfacescount; i++) {
1353 h2 = class_highestinterface(c->interfaces[i]);
1362 #if defined(__cplusplus)
1367 * These are local overrides for various environment variables in Emacs.
1368 * Please do not remove this and leave it at the end of the file, where
1369 * Emacs will automagically detect them.
1370 * ---------------------------------------------------------------------
1373 * indent-tabs-mode: t
1377 * vim:noexpandtab:sw=4:ts=4: