1 /* src/vmcore/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.h"
37 #include "native/native.h"
39 #include "threads/lock-common.h"
41 #include "toolbox/logging.h"
43 #include "vm/access.h"
45 #include "vm/exceptions.h"
46 #include "vm/primitive.h"
47 #include "vm/stringlocal.h"
50 #include "vm/jit_interface.h"
52 #include "vmcore/class.h"
53 #include "vmcore/classcache.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/options.h"
56 #include "vmcore/rt-timing.h"
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 "vmcore/statistics.h"
85 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
86 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
88 #define INLINELOG(code)
92 /* global variables ***********************************************************/
94 static s4 interfaceindex; /* sequential numbering of interfaces */
97 java_object_t *linker_classrenumber_lock;
100 /* private functions **********************************************************/
102 static classinfo *link_class_intern(classinfo *c);
103 static arraydescriptor *link_array(classinfo *c);
104 static void linker_compute_class_values(classinfo *c);
105 static void linker_compute_subclasses(classinfo *c);
106 static bool linker_addinterface(classinfo *c, classinfo *ic);
107 static s4 class_highestinterface(classinfo *c);
110 /* dummy structures for alinment checks ***************************************/
112 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
113 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
115 struct dummy_alignment_long_t {
120 struct dummy_alignment_double_t {
126 /* linker_init *****************************************************************
128 Initializes the linker subsystem and links classes required for the
131 *******************************************************************************/
133 void linker_preinit(void)
135 /* Check for if alignment for long and double matches what we
136 assume for the current architecture. */
138 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
139 if (OFFSET(dummy_alignment_long_t, l) != 4)
140 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
141 OFFSET(dummy_alignment_long_t, l), 4);
143 if (OFFSET(dummy_alignment_double_t, d) != 4)
144 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
145 OFFSET(dummy_alignment_double_t, d), 4);
147 if (OFFSET(dummy_alignment_long_t, l) != 8)
148 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
149 OFFSET(dummy_alignment_long_t, l), 8);
151 if (OFFSET(dummy_alignment_double_t, d) != 8)
152 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
153 OFFSET(dummy_alignment_double_t, d), 8);
156 /* Reset interface index. */
160 #if defined(ENABLE_THREADS)
161 /* create the global lock object */
163 linker_classrenumber_lock = NEW(java_object_t);
165 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
168 /* Link the most basic classes. */
170 if (!link_class(class_java_lang_Object))
171 vm_abort("linker_preinit: linking java/lang/Object failed");
173 #if defined(ENABLE_JAVASE)
174 if (!link_class(class_java_lang_Cloneable))
175 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
177 if (!link_class(class_java_io_Serializable))
178 vm_abort("linker_preinit: linking java/io/Serializable failed");
183 /* linker_init *****************************************************************
185 Links all classes required in the VM.
187 *******************************************************************************/
189 void linker_init(void)
191 /* Link java.lang.Class as first class of the system, because we
192 need it's vftbl for all other classes so we can use a class as
195 if (!link_class(class_java_lang_Class))
196 vm_abort("linker_init: linking java/lang/Class failed");
198 /* Now set the header.vftbl of all classes which were created
199 before java.lang.Class was linked. */
201 class_postset_header_vftbl();
203 /* Link primitive-type wrapping classes. */
205 #if defined(ENABLE_JAVASE)
206 if (!link_class(class_java_lang_Void))
207 vm_abort("linker_init: linking failed");
210 if (!link_class(class_java_lang_Boolean))
211 vm_abort("linker_init: linking failed");
213 if (!link_class(class_java_lang_Byte))
214 vm_abort("linker_init: linking failed");
216 if (!link_class(class_java_lang_Character))
217 vm_abort("linker_init: linking failed");
219 if (!link_class(class_java_lang_Short))
220 vm_abort("linker_init: linking failed");
222 if (!link_class(class_java_lang_Integer))
223 vm_abort("linker_init: linking failed");
225 if (!link_class(class_java_lang_Long))
226 vm_abort("linker_init: linking failed");
228 if (!link_class(class_java_lang_Float))
229 vm_abort("linker_init: linking failed");
231 if (!link_class(class_java_lang_Double))
232 vm_abort("linker_init: linking failed");
234 /* Link important system classes. */
236 if (!link_class(class_java_lang_String))
237 vm_abort("linker_init: linking java/lang/String failed");
239 #if defined(ENABLE_JAVASE)
240 if (!link_class(class_java_lang_ClassLoader))
241 vm_abort("linker_init: linking failed");
243 if (!link_class(class_java_lang_SecurityManager))
244 vm_abort("linker_init: linking failed");
247 if (!link_class(class_java_lang_System))
248 vm_abort("linker_init: linking failed");
250 if (!link_class(class_java_lang_Thread))
251 vm_abort("linker_init: linking failed");
253 #if defined(ENABLE_JAVASE)
254 if (!link_class(class_java_lang_ThreadGroup))
255 vm_abort("linker_init: linking failed");
258 if (!link_class(class_java_lang_Throwable))
259 vm_abort("linker_init: linking failed");
261 #if defined(WITH_CLASSPATH_GNU)
262 if (!link_class(class_java_lang_VMSystem))
263 vm_abort("linker_init: linking failed");
265 if (!link_class(class_java_lang_VMThread))
266 vm_abort("linker_init: linking failed");
268 if (!link_class(class_java_lang_VMThrowable))
269 vm_abort("linker_init: linking failed");
273 /* some classes which may be used more often */
275 #if defined(ENABLE_JAVASE)
276 if (!link_class(class_java_lang_StackTraceElement))
277 vm_abort("linker_init: linking failed");
279 if (!link_class(class_java_lang_reflect_Constructor))
280 vm_abort("linker_init: linking failed");
282 if (!link_class(class_java_lang_reflect_Field))
283 vm_abort("linker_init: linking failed");
285 if (!link_class(class_java_lang_reflect_Method))
286 vm_abort("linker_init: linking failed");
288 if (!link_class(class_java_security_PrivilegedAction))
289 vm_abort("linker_init: linking failed");
291 if (!link_class(class_java_util_Vector))
292 vm_abort("linker_init: linking failed");
294 # if defined(WITH_CLASSPATH_SUN)
295 if (!link_class(class_sun_reflect_MagicAccessorImpl))
296 vm_abort("linker_init: linking failed");
299 if (!link_class(arrayclass_java_lang_Object))
300 vm_abort("linker_init: linking failed");
304 /* create pseudo classes used by the typechecker */
306 /* pseudo class for Arraystubs (extends java.lang.Object) */
308 pseudo_class_Arraystub =
309 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
310 pseudo_class_Arraystub->state |= CLASS_LOADED;
311 pseudo_class_Arraystub->super = class_java_lang_Object;
313 #if defined(ENABLE_JAVASE)
315 pseudo_class_Arraystub->interfacescount = 2;
316 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
317 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
318 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
320 #elif defined(ENABLE_JAVAME_CLDC1_1)
322 pseudo_class_Arraystub->interfacescount = 0;
323 pseudo_class_Arraystub->interfaces = NULL;
326 # error unknown Java configuration
329 if (!classcache_store_unique(pseudo_class_Arraystub))
330 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
332 if (!link_class(pseudo_class_Arraystub))
333 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
335 /* pseudo class representing the null type */
337 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
338 pseudo_class_Null->state |= CLASS_LOADED;
339 pseudo_class_Null->super = class_java_lang_Object;
341 if (!classcache_store_unique(pseudo_class_Null))
342 vm_abort("linker_init: could not cache pseudo_class_Null");
344 if (!link_class(pseudo_class_Null))
345 vm_abort("linker_init: linking failed");
347 /* pseudo class representing new uninitialized objects */
349 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
350 pseudo_class_New->state |= CLASS_LOADED;
351 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
352 pseudo_class_New->super = class_java_lang_Object;
354 if (!classcache_store_unique(pseudo_class_New))
355 vm_abort("linker_init: could not cache pseudo_class_New");
357 /* Correct vftbl-entries (retarded loading and linking of class
358 java/lang/String). */
360 stringtable_update();
364 /* link_class ******************************************************************
366 Wrapper function for link_class_intern to ease monitor enter/exit
367 and exception handling.
369 *******************************************************************************/
371 classinfo *link_class(classinfo *c)
374 #if defined(ENABLE_RT_TIMING)
375 struct timespec time_start, time_end;
378 RT_TIMING_GET_TIME(time_start);
381 exceptions_throw_nullpointerexception();
385 LOCK_MONITOR_ENTER(c);
387 /* Maybe the class is currently linking or is already linked.*/
389 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
390 LOCK_MONITOR_EXIT(c);
395 #if defined(ENABLE_STATISTICS)
398 if (opt_getcompilingtime)
399 compilingtime_stop();
401 if (opt_getloadingtime)
405 /* call the internal function */
407 r = link_class_intern(c);
409 /* If return value is NULL, we had a problem and the class is not
413 c->state &= ~CLASS_LINKING;
415 #if defined(ENABLE_STATISTICS)
418 if (opt_getloadingtime)
421 if (opt_getcompilingtime)
422 compilingtime_start();
425 LOCK_MONITOR_EXIT(c);
427 RT_TIMING_GET_TIME(time_end);
429 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
435 /* linker_overwrite_method *****************************************************
437 Overwrite a method with another one, update method flags and check
441 mg................the general method being overwritten
442 ms................the overwriting (more specialized) method
443 wl................worklist where to add invalidated methods
446 true..............everything ok
447 false.............an exception has been thrown
449 *******************************************************************************/
451 static bool linker_overwrite_method(methodinfo *mg,
453 method_worklist **wl)
461 /* overriding a final method is illegal */
463 if (mg->flags & ACC_FINAL) {
464 exceptions_throw_verifyerror(mg, "Overriding final method");
468 /* method ms overwrites method mg */
470 #if defined(ENABLE_VERIFIER)
471 /* Add loading constraints (for the more general types of method mg). */
472 /* Not for <init>, as it is not invoked virtually. */
474 if ((ms->name != utf_init)
475 && !classcache_add_constraints_for_params(
476 cs->classloader, cg->classloader, mg))
482 /* inherit the vftbl index, and record the overwriting */
484 ms->vftblindex = mg->vftblindex;
487 /* update flags and check assumptions */
488 /* <init> methods are a special case, as they are never dispatched dynamically */
490 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
492 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
493 /* this adds another implementation */
495 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
497 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
499 method_break_assumption_monomorphic(mg, wl);
502 /* this is the first implementation */
504 mg->flags |= ACC_METHOD_IMPLEMENTED;
506 INLINELOG( printf("becomes implemented: "); method_println(mg); );
511 } while (mg != NULL);
518 /* link_class_intern ***********************************************************
520 Tries to link a class. The function calculates the length in bytes
521 that an instance of this class requires as well as the VTBL for
522 methods and interface methods.
524 *******************************************************************************/
526 static classinfo *link_class_intern(classinfo *c)
528 classinfo *super; /* super class */
529 classinfo *tc; /* temporary class variable */
530 s4 supervftbllength; /* vftbllegnth of super class */
531 s4 vftbllength; /* vftbllength of current class */
532 s4 interfacetablelength; /* interface table length */
533 vftbl_t *v; /* vftbl of current class */
534 s4 i; /* interface/method/field counter */
535 arraydescriptor *arraydesc; /* descriptor for array classes */
536 method_worklist *worklist; /* worklist for recompilation */
537 #if defined(ENABLE_RT_TIMING)
538 struct timespec time_start, time_resolving, time_compute_vftbl,
539 time_abstract, time_compute_iftbl, time_fill_vftbl,
540 time_offsets, time_fill_iftbl, time_finalizer,
544 RT_TIMING_GET_TIME(time_start);
548 /* the class must be loaded */
550 /* XXX should this be a specific exception? */
551 assert(c->state & CLASS_LOADED);
553 /* This is check in link_class. */
555 assert(!(c->state & CLASS_LINKED));
557 /* cache the self-reference of this class */
558 /* we do this for cases where the defining loader of the class */
559 /* has not yet been recorded as an initiating loader for the class */
560 /* this is needed so subsequent code can assume that self-refs */
561 /* will always resolve lazily */
562 /* No need to do it for the bootloader - it is always registered */
563 /* as initiating loader for the classes it loads. */
565 classcache_store(c->classloader,c,false);
567 /* this class is currently linking */
569 c->state |= CLASS_LINKING;
574 /* Link the super interfaces. */
576 for (i = 0; i < c->interfacescount; i++) {
577 tc = c->interfaces[i];
579 if (!(tc->state & CLASS_LINKED))
584 /* check super class */
588 /* Check for java/lang/Object. */
590 if (c->super == NULL) {
592 c->instancesize = sizeof(java_object_t);
594 vftbllength = supervftbllength = 0;
599 /* Get super class. */
603 /* Link the super class if necessary. */
605 if (!(super->state & CLASS_LINKED))
606 if (!link_class(super))
609 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
612 c->flags |= (super->flags &
613 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
615 /* handle array classes */
617 if (c->name->text[0] == '[')
618 if (!(arraydesc = link_array(c)))
621 if (c->flags & ACC_INTERFACE)
622 c->index = interfaceindex++;
624 c->index = super->index + 1;
626 c->instancesize = super->instancesize;
628 vftbllength = supervftbllength = super->vftbl->vftbllength;
630 c->finalizer = super->finalizer;
632 RT_TIMING_GET_TIME(time_resolving);
635 /* compute vftbl length */
637 for (i = 0; i < c->methodscount; i++) {
638 methodinfo *m = &(c->methods[i]);
640 if (!(m->flags & ACC_STATIC)) { /* is instance method */
646 for (j = 0; j < tc->methodscount; j++) {
647 if (method_canoverwrite(m, &(tc->methods[j]))) {
648 if (tc->methods[j].flags & ACC_PRIVATE)
649 goto notfoundvftblindex;
651 /* package-private methods in other packages */
652 /* must not be overridden */
653 /* (see Java Language Specification 8.4.8.1) */
654 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
655 && !SAME_PACKAGE(c,tc) )
657 goto notfoundvftblindex;
660 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
663 goto foundvftblindex;
671 m->vftblindex = (vftbllength++);
676 RT_TIMING_GET_TIME(time_compute_vftbl);
679 /* Check all interfaces of an abstract class (maybe be an
680 interface too) for unimplemented methods. Such methods are
681 called miranda-methods and are marked with the ACC_MIRANDA
682 flag. VMClass.getDeclaredMethods does not return such
685 if (c->flags & ACC_ABSTRACT) {
688 s4 abstractmethodscount;
692 abstractmethodscount = 0;
694 /* check all interfaces of the abstract class */
696 for (i = 0; i < c->interfacescount; i++) {
697 ic = c->interfaces[i];
699 for (j = 0; j < ic->methodscount; j++) {
700 im = &(ic->methods[j]);
702 /* skip `<clinit>' and `<init>' */
704 if ((im->name == utf_clinit) || (im->name == utf_init))
707 for (tc = c; tc != NULL; tc = tc->super) {
708 for (k = 0; k < tc->methodscount; k++) {
709 if (method_canoverwrite(im, &(tc->methods[k])))
710 goto noabstractmethod;
714 abstractmethodscount++;
721 if (abstractmethodscount > 0) {
724 /* reallocate methods memory */
726 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
727 c->methodscount + abstractmethodscount);
729 for (i = 0; i < c->interfacescount; i++) {
730 ic = c->interfaces[i];
732 for (j = 0; j < ic->methodscount; j++) {
733 im = &(ic->methods[j]);
735 /* skip `<clinit>' and `<init>' */
737 if ((im->name == utf_clinit) || (im->name == utf_init))
740 for (tc = c; tc != NULL; tc = tc->super) {
741 for (k = 0; k < tc->methodscount; k++) {
742 if (method_canoverwrite(im, &(tc->methods[k])))
743 goto noabstractmethod2;
747 /* Copy the method found into the new c->methods
748 array and tag it as miranda-method. */
750 am = &(c->methods[c->methodscount]);
753 MCOPY(am, im, methodinfo, 1);
755 am->vftblindex = (vftbllength++);
757 am->flags |= ACC_MIRANDA;
765 RT_TIMING_GET_TIME(time_abstract);
768 #if defined(ENABLE_STATISTICS)
771 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
774 /* compute interfacetable length */
776 interfacetablelength = 0;
778 for (tc = c; tc != NULL; tc = tc->super) {
779 for (i = 0; i < tc->interfacescount; i++) {
780 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
782 if (h > interfacetablelength)
783 interfacetablelength = h;
786 RT_TIMING_GET_TIME(time_compute_iftbl);
788 /* allocate virtual function table */
790 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
791 sizeof(methodptr) * (vftbllength - 1) +
792 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
793 v = (vftbl_t *) (((methodptr *) v) +
794 (interfacetablelength - 1) * (interfacetablelength > 1));
798 v->vftbllength = vftbllength;
799 v->interfacetablelength = interfacetablelength;
800 v->arraydesc = arraydesc;
802 /* store interface index in vftbl */
804 if (c->flags & ACC_INTERFACE)
805 v->baseval = -(c->index);
807 /* copy virtual function table of super class */
809 for (i = 0; i < supervftbllength; i++)
810 v->table[i] = super->vftbl->table[i];
812 /* Fill the remaining vftbl slots with the AbstractMethodError
813 stub (all after the super class slots, because they are already
816 for (; i < vftbllength; i++) {
817 #if defined(ENABLE_JIT)
818 # if defined(ENABLE_INTRP)
820 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
823 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
825 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
829 /* add method stubs into virtual function table */
831 for (i = 0; i < c->methodscount; i++) {
832 methodinfo *m = &(c->methods[i]);
834 assert(m->stubroutine == NULL);
836 /* Don't create a compiler stub for abstract methods as they
837 throw an AbstractMethodError with the default stub in the
838 vftbl. This entry is simply copied by sub-classes. */
840 if (m->flags & ACC_ABSTRACT)
843 #if defined(ENABLE_JIT)
844 # if defined(ENABLE_INTRP)
846 m->stubroutine = intrp_createcompilerstub(m);
849 m->stubroutine = codegen_generate_stub_compiler(m);
851 m->stubroutine = intrp_createcompilerstub(m);
854 /* static methods are not in the vftbl */
856 if (m->flags & ACC_STATIC)
859 /* insert the stubroutine into the vftbl */
861 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
863 RT_TIMING_GET_TIME(time_fill_vftbl);
865 /* compute instance size and offset of each field */
867 for (i = 0; i < c->fieldscount; i++) {
869 fieldinfo *f = &(c->fields[i]);
871 if (!(f->flags & ACC_STATIC)) {
872 dsize = descriptor_typesize(f->parseddesc);
874 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
875 /* On i386 and ARM we align double and s8 fields to
876 4-bytes. This matches what GCC does for struct
877 members. We must do the same as gcc here because the
878 offsets in native header structs like java_lang_Double
879 must match the offsets of the Java fields
880 (eg. java.lang.Double.value). */
882 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
884 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
887 f->offset = c->instancesize;
888 c->instancesize += dsize;
891 RT_TIMING_GET_TIME(time_offsets);
893 /* initialize interfacetable and interfacevftbllength */
895 v->interfacevftbllength = MNEW(s4, interfacetablelength);
897 #if defined(ENABLE_STATISTICS)
899 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
902 for (i = 0; i < interfacetablelength; i++) {
903 v->interfacevftbllength[i] = 0;
904 v->interfacetable[-i] = NULL;
909 for (tc = c; tc != NULL; tc = tc->super)
910 for (i = 0; i < tc->interfacescount; i++)
911 if (!linker_addinterface(c, tc->interfaces[i]))
914 RT_TIMING_GET_TIME(time_fill_iftbl);
916 /* add finalizer method (not for java.lang.Object) */
921 fi = class_findmethod(c, utf_finalize, utf_void__void);
924 if (!(fi->flags & ACC_STATIC))
927 RT_TIMING_GET_TIME(time_finalizer);
931 linker_compute_subclasses(c);
933 RT_TIMING_GET_TIME(time_subclasses);
935 /* revert the linking state and class is linked */
937 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
941 /* XXX must this also be done in case of exception? */
943 while (worklist != NULL) {
944 method_worklist *wi = worklist;
946 worklist = worklist->next;
948 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
949 jit_invalidate_code(wi->m);
951 /* XXX put worklist into dump memory? */
952 FREE(wi, method_worklist);
955 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
956 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
957 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
958 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
959 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
960 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
961 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
962 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
963 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
965 /* just return c to show that we didn't had a problem */
971 /* link_array ******************************************************************
973 This function is called by link_class to create the arraydescriptor
976 This function returns NULL if the array cannot be linked because
977 the component type has not been linked yet.
979 *******************************************************************************/
981 static arraydescriptor *link_array(classinfo *c)
985 arraydescriptor *desc;
990 namelen = c->name->blength;
992 /* Check the component type */
994 switch (c->name->text[1]) {
996 /* c is an array of arrays. */
997 u = utf_new(c->name->text + 1, namelen - 1);
998 if (!(comp = load_class_from_classloader(u, c->classloader)))
1003 /* c is an array of objects. */
1004 u = utf_new(c->name->text + 2, namelen - 3);
1005 if (!(comp = load_class_from_classloader(u, c->classloader)))
1010 /* If the component type has not been linked, link it now */
1012 assert(!comp || (comp->state & CLASS_LOADED));
1014 if (comp && !(comp->state & CLASS_LINKED))
1015 if (!link_class(comp))
1018 /* Allocate the arraydescriptor */
1020 desc = NEW(arraydescriptor);
1023 /* c is an array of references */
1024 desc->arraytype = ARRAYTYPE_OBJECT;
1025 desc->componentsize = sizeof(void*);
1026 desc->dataoffset = OFFSET(java_objectarray_t, data);
1028 compvftbl = comp->vftbl;
1031 log_text("Component class has no vftbl");
1035 desc->componentvftbl = compvftbl;
1037 if (compvftbl->arraydesc) {
1038 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1040 if (compvftbl->arraydesc->dimension >= 255) {
1041 log_text("Creating array of dimension >255");
1045 desc->dimension = compvftbl->arraydesc->dimension + 1;
1046 desc->elementtype = compvftbl->arraydesc->elementtype;
1049 desc->elementvftbl = compvftbl;
1050 desc->dimension = 1;
1051 desc->elementtype = ARRAYTYPE_OBJECT;
1055 /* c is an array of a primitive type */
1056 switch (c->name->text[1]) {
1058 desc->arraytype = ARRAYTYPE_BOOLEAN;
1059 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1060 desc->componentsize = sizeof(u1);
1064 desc->arraytype = ARRAYTYPE_BYTE;
1065 desc->dataoffset = OFFSET(java_bytearray_t,data);
1066 desc->componentsize = sizeof(u1);
1070 desc->arraytype = ARRAYTYPE_CHAR;
1071 desc->dataoffset = OFFSET(java_chararray_t,data);
1072 desc->componentsize = sizeof(u2);
1076 desc->arraytype = ARRAYTYPE_DOUBLE;
1077 desc->dataoffset = OFFSET(java_doublearray_t,data);
1078 desc->componentsize = sizeof(double);
1082 desc->arraytype = ARRAYTYPE_FLOAT;
1083 desc->dataoffset = OFFSET(java_floatarray_t,data);
1084 desc->componentsize = sizeof(float);
1088 desc->arraytype = ARRAYTYPE_INT;
1089 desc->dataoffset = OFFSET(java_intarray_t,data);
1090 desc->componentsize = sizeof(s4);
1094 desc->arraytype = ARRAYTYPE_LONG;
1095 desc->dataoffset = OFFSET(java_longarray_t,data);
1096 desc->componentsize = sizeof(s8);
1100 desc->arraytype = ARRAYTYPE_SHORT;
1101 desc->dataoffset = OFFSET(java_shortarray_t,data);
1102 desc->componentsize = sizeof(s2);
1106 exceptions_throw_noclassdeffounderror(c->name);
1110 desc->componentvftbl = NULL;
1111 desc->elementvftbl = NULL;
1112 desc->dimension = 1;
1113 desc->elementtype = desc->arraytype;
1120 /* linker_compute_subclasses ***************************************************
1124 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1125 This function needs to take the class renumber lock and stop the
1126 world during class renumbering. The lock is used in C code which
1127 is not that performance critical. Whereas JIT code uses critical
1128 sections to atomically access the class values.
1130 *******************************************************************************/
1132 static void linker_compute_subclasses(classinfo *c)
1134 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1136 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1137 threads_stopworld();
1140 if (!(c->flags & ACC_INTERFACE)) {
1145 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1146 c->nextsub = c->super->sub;
1152 /* compute class values */
1154 linker_compute_class_values(class_java_lang_Object);
1156 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1158 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1159 threads_startworld();
1164 /* linker_compute_class_values *************************************************
1168 *******************************************************************************/
1170 static void linker_compute_class_values(classinfo *c)
1174 c->vftbl->baseval = ++classvalue;
1179 linker_compute_class_values(subs);
1181 subs = subs->nextsub;
1184 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1188 /* linker_addinterface *********************************************************
1190 Is needed by link_class for adding a VTBL to a class. All
1191 interfaces implemented by ic are added as well.
1194 true.........everything ok
1195 false........an exception has been thrown
1197 *******************************************************************************/
1199 static bool linker_addinterface(classinfo *c, classinfo *ic)
1210 if (i >= v->interfacetablelength)
1211 vm_abort("Internal error: interfacetable overflow");
1213 /* if this interface has already been added, return immediately */
1215 if (v->interfacetable[-i] != NULL)
1218 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1219 v->interfacevftbllength[i] = 1;
1220 v->interfacetable[-i] = MNEW(methodptr, 1);
1221 v->interfacetable[-i][0] = NULL;
1224 v->interfacevftbllength[i] = ic->methodscount;
1225 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1227 #if defined(ENABLE_STATISTICS)
1229 count_vftbl_len += sizeof(methodptr) *
1230 (ic->methodscount + (ic->methodscount == 0));
1233 for (j = 0; j < ic->methodscount; j++) {
1234 for (sc = c; sc != NULL; sc = sc->super) {
1235 for (k = 0; k < sc->methodscount; k++) {
1236 m = &(sc->methods[k]);
1238 if (method_canoverwrite(m, &(ic->methods[j]))) {
1239 /* method m overwrites the (abstract) method */
1240 #if defined(ENABLE_VERIFIER)
1241 /* Add loading constraints (for the more
1242 general types of the method
1244 if (!classcache_add_constraints_for_params(
1245 c->classloader, ic->classloader,
1252 /* XXX taken from gcj */
1253 /* check for ACC_STATIC: IncompatibleClassChangeError */
1255 /* check for !ACC_PUBLIC: IllegalAccessError */
1257 /* check for ACC_ABSTRACT: AbstracMethodError,
1258 not sure about that one */
1260 v->interfacetable[-i][j] = v->table[m->vftblindex];
1266 /* If no method was found, insert the AbstractMethodError
1269 #if defined(ENABLE_JIT)
1270 # if defined(ENABLE_INTRP)
1272 v->interfacetable[-i][j] =
1273 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1276 v->interfacetable[-i][j] =
1277 (methodptr) (ptrint) &asm_abstractmethoderror;
1279 v->interfacetable[-i][j] =
1280 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1288 /* add superinterfaces of this interface */
1290 for (j = 0; j < ic->interfacescount; j++)
1291 if (!linker_addinterface(c, ic->interfaces[j]))
1300 /* class_highestinterface ******************************************************
1302 Used by the function link_class to determine the amount of memory
1303 needed for the interface table.
1305 *******************************************************************************/
1307 static s4 class_highestinterface(classinfo *c)
1313 /* check for ACC_INTERFACE bit already done in link_class_intern */
1317 for (i = 0; i < c->interfacescount; i++) {
1318 h2 = class_highestinterface(c->interfaces[i]);
1329 * These are local overrides for various environment variables in Emacs.
1330 * Please do not remove this and leave it at the end of the file, where
1331 * Emacs will automagically detect them.
1332 * ---------------------------------------------------------------------
1335 * indent-tabs-mode: t
1339 * vim:noexpandtab:sw=4:ts=4: