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 (!link_class(class_java_util_HashMap))
295 vm_abort("linker_init: linking failed");
297 # if defined(WITH_CLASSPATH_SUN)
298 if (!link_class(class_sun_reflect_MagicAccessorImpl))
299 vm_abort("linker_init: linking failed");
302 if (!link_class(arrayclass_java_lang_Object))
303 vm_abort("linker_init: linking failed");
307 /* create pseudo classes used by the typechecker */
309 /* pseudo class for Arraystubs (extends java.lang.Object) */
311 pseudo_class_Arraystub =
312 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
313 pseudo_class_Arraystub->state |= CLASS_LOADED;
314 pseudo_class_Arraystub->super = class_java_lang_Object;
316 #if defined(ENABLE_JAVASE)
318 pseudo_class_Arraystub->interfacescount = 2;
319 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
320 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
321 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
323 #elif defined(ENABLE_JAVAME_CLDC1_1)
325 pseudo_class_Arraystub->interfacescount = 0;
326 pseudo_class_Arraystub->interfaces = NULL;
329 # error unknown Java configuration
332 if (!classcache_store_unique(pseudo_class_Arraystub))
333 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
335 if (!link_class(pseudo_class_Arraystub))
336 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
338 /* pseudo class representing the null type */
340 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
341 pseudo_class_Null->state |= CLASS_LOADED;
342 pseudo_class_Null->super = class_java_lang_Object;
344 if (!classcache_store_unique(pseudo_class_Null))
345 vm_abort("linker_init: could not cache pseudo_class_Null");
347 if (!link_class(pseudo_class_Null))
348 vm_abort("linker_init: linking failed");
350 /* pseudo class representing new uninitialized objects */
352 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
353 pseudo_class_New->state |= CLASS_LOADED;
354 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
355 pseudo_class_New->super = class_java_lang_Object;
357 if (!classcache_store_unique(pseudo_class_New))
358 vm_abort("linker_init: could not cache pseudo_class_New");
360 /* Correct vftbl-entries (retarded loading and linking of class
361 java/lang/String). */
363 stringtable_update();
367 /* link_class ******************************************************************
369 Wrapper function for link_class_intern to ease monitor enter/exit
370 and exception handling.
372 *******************************************************************************/
374 classinfo *link_class(classinfo *c)
377 #if defined(ENABLE_RT_TIMING)
378 struct timespec time_start, time_end;
381 RT_TIMING_GET_TIME(time_start);
384 exceptions_throw_nullpointerexception();
388 LOCK_MONITOR_ENTER(c);
390 /* Maybe the class is currently linking or is already linked.*/
392 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
393 LOCK_MONITOR_EXIT(c);
398 #if defined(ENABLE_STATISTICS)
401 if (opt_getcompilingtime)
402 compilingtime_stop();
404 if (opt_getloadingtime)
408 /* call the internal function */
410 r = link_class_intern(c);
412 /* If return value is NULL, we had a problem and the class is not
416 c->state &= ~CLASS_LINKING;
418 #if defined(ENABLE_STATISTICS)
421 if (opt_getloadingtime)
424 if (opt_getcompilingtime)
425 compilingtime_start();
428 LOCK_MONITOR_EXIT(c);
430 RT_TIMING_GET_TIME(time_end);
432 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
438 /* linker_overwrite_method *****************************************************
440 Overwrite a method with another one, update method flags and check
444 mg................the general method being overwritten
445 ms................the overwriting (more specialized) method
446 wl................worklist where to add invalidated methods
449 true..............everything ok
450 false.............an exception has been thrown
452 *******************************************************************************/
454 static bool linker_overwrite_method(methodinfo *mg,
456 method_worklist **wl)
464 /* overriding a final method is illegal */
466 if (mg->flags & ACC_FINAL) {
467 exceptions_throw_verifyerror(mg, "Overriding final method");
471 /* method ms overwrites method mg */
473 #if defined(ENABLE_VERIFIER)
474 /* Add loading constraints (for the more general types of method mg). */
475 /* Not for <init>, as it is not invoked virtually. */
477 if ((ms->name != utf_init)
478 && !classcache_add_constraints_for_params(
479 cs->classloader, cg->classloader, mg))
485 /* inherit the vftbl index, and record the overwriting */
487 ms->vftblindex = mg->vftblindex;
490 /* update flags and check assumptions */
491 /* <init> methods are a special case, as they are never dispatched dynamically */
493 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
495 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
496 /* this adds another implementation */
498 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
500 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
502 method_break_assumption_monomorphic(mg, wl);
505 /* this is the first implementation */
507 mg->flags |= ACC_METHOD_IMPLEMENTED;
509 INLINELOG( printf("becomes implemented: "); method_println(mg); );
514 } while (mg != NULL);
521 /* link_class_intern ***********************************************************
523 Tries to link a class. The function calculates the length in bytes
524 that an instance of this class requires as well as the VTBL for
525 methods and interface methods.
527 *******************************************************************************/
529 static classinfo *link_class_intern(classinfo *c)
531 classinfo *super; /* super class */
532 classinfo *tc; /* temporary class variable */
533 s4 supervftbllength; /* vftbllegnth of super class */
534 s4 vftbllength; /* vftbllength of current class */
535 s4 interfacetablelength; /* interface table length */
536 vftbl_t *v; /* vftbl of current class */
537 s4 i; /* interface/method/field counter */
538 arraydescriptor *arraydesc; /* descriptor for array classes */
539 method_worklist *worklist; /* worklist for recompilation */
540 #if defined(ENABLE_RT_TIMING)
541 struct timespec time_start, time_resolving, time_compute_vftbl,
542 time_abstract, time_compute_iftbl, time_fill_vftbl,
543 time_offsets, time_fill_iftbl, time_finalizer,
547 RT_TIMING_GET_TIME(time_start);
551 /* the class must be loaded */
553 /* XXX should this be a specific exception? */
554 assert(c->state & CLASS_LOADED);
556 /* This is check in link_class. */
558 assert(!(c->state & CLASS_LINKED));
560 /* cache the self-reference of this class */
561 /* we do this for cases where the defining loader of the class */
562 /* has not yet been recorded as an initiating loader for the class */
563 /* this is needed so subsequent code can assume that self-refs */
564 /* will always resolve lazily */
565 /* No need to do it for the bootloader - it is always registered */
566 /* as initiating loader for the classes it loads. */
568 classcache_store(c->classloader,c,false);
570 /* this class is currently linking */
572 c->state |= CLASS_LINKING;
577 /* Link the super interfaces. */
579 for (i = 0; i < c->interfacescount; i++) {
580 tc = c->interfaces[i];
582 if (!(tc->state & CLASS_LINKED))
587 /* check super class */
591 /* Check for java/lang/Object. */
593 if (c->super == NULL) {
595 c->instancesize = sizeof(java_object_t);
597 vftbllength = supervftbllength = 0;
602 /* Get super class. */
606 /* Link the super class if necessary. */
608 if (!(super->state & CLASS_LINKED))
609 if (!link_class(super))
612 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
615 c->flags |= (super->flags &
616 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
618 /* handle array classes */
620 if (c->name->text[0] == '[')
621 if (!(arraydesc = link_array(c)))
624 if (c->flags & ACC_INTERFACE)
625 c->index = interfaceindex++;
627 c->index = super->index + 1;
629 c->instancesize = super->instancesize;
631 vftbllength = supervftbllength = super->vftbl->vftbllength;
633 c->finalizer = super->finalizer;
635 RT_TIMING_GET_TIME(time_resolving);
638 /* compute vftbl length */
640 for (i = 0; i < c->methodscount; i++) {
641 methodinfo *m = &(c->methods[i]);
643 if (!(m->flags & ACC_STATIC)) { /* is instance method */
649 for (j = 0; j < tc->methodscount; j++) {
650 if (method_canoverwrite(m, &(tc->methods[j]))) {
651 if (tc->methods[j].flags & ACC_PRIVATE)
652 goto notfoundvftblindex;
654 /* package-private methods in other packages */
655 /* must not be overridden */
656 /* (see Java Language Specification 8.4.8.1) */
657 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
658 && !SAME_PACKAGE(c,tc) )
660 goto notfoundvftblindex;
663 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
666 goto foundvftblindex;
674 m->vftblindex = (vftbllength++);
679 RT_TIMING_GET_TIME(time_compute_vftbl);
682 /* Check all interfaces of an abstract class (maybe be an
683 interface too) for unimplemented methods. Such methods are
684 called miranda-methods and are marked with the ACC_MIRANDA
685 flag. VMClass.getDeclaredMethods does not return such
688 if (c->flags & ACC_ABSTRACT) {
691 s4 abstractmethodscount;
695 abstractmethodscount = 0;
697 /* check all interfaces of the abstract class */
699 for (i = 0; i < c->interfacescount; i++) {
700 ic = c->interfaces[i];
702 for (j = 0; j < ic->methodscount; j++) {
703 im = &(ic->methods[j]);
705 /* skip `<clinit>' and `<init>' */
707 if ((im->name == utf_clinit) || (im->name == utf_init))
710 for (tc = c; tc != NULL; tc = tc->super) {
711 for (k = 0; k < tc->methodscount; k++) {
712 if (method_canoverwrite(im, &(tc->methods[k])))
713 goto noabstractmethod;
717 abstractmethodscount++;
724 if (abstractmethodscount > 0) {
727 /* reallocate methods memory */
729 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
730 c->methodscount + abstractmethodscount);
732 for (i = 0; i < c->interfacescount; i++) {
733 ic = c->interfaces[i];
735 for (j = 0; j < ic->methodscount; j++) {
736 im = &(ic->methods[j]);
738 /* skip `<clinit>' and `<init>' */
740 if ((im->name == utf_clinit) || (im->name == utf_init))
743 for (tc = c; tc != NULL; tc = tc->super) {
744 for (k = 0; k < tc->methodscount; k++) {
745 if (method_canoverwrite(im, &(tc->methods[k])))
746 goto noabstractmethod2;
750 /* Copy the method found into the new c->methods
751 array and tag it as miranda-method. */
753 am = &(c->methods[c->methodscount]);
756 MCOPY(am, im, methodinfo, 1);
758 am->vftblindex = (vftbllength++);
760 am->flags |= ACC_MIRANDA;
768 RT_TIMING_GET_TIME(time_abstract);
771 #if defined(ENABLE_STATISTICS)
774 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
777 /* compute interfacetable length */
779 interfacetablelength = 0;
781 for (tc = c; tc != NULL; tc = tc->super) {
782 for (i = 0; i < tc->interfacescount; i++) {
783 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
785 if (h > interfacetablelength)
786 interfacetablelength = h;
789 RT_TIMING_GET_TIME(time_compute_iftbl);
791 /* allocate virtual function table */
793 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
794 sizeof(methodptr) * (vftbllength - 1) +
795 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
796 v = (vftbl_t *) (((methodptr *) v) +
797 (interfacetablelength - 1) * (interfacetablelength > 1));
801 v->vftbllength = vftbllength;
802 v->interfacetablelength = interfacetablelength;
803 v->arraydesc = arraydesc;
805 /* store interface index in vftbl */
807 if (c->flags & ACC_INTERFACE)
808 v->baseval = -(c->index);
810 /* copy virtual function table of super class */
812 for (i = 0; i < supervftbllength; i++)
813 v->table[i] = super->vftbl->table[i];
815 /* Fill the remaining vftbl slots with the AbstractMethodError
816 stub (all after the super class slots, because they are already
819 for (; i < vftbllength; i++) {
820 #if defined(ENABLE_JIT)
821 # if defined(ENABLE_INTRP)
823 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
826 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
828 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
832 /* add method stubs into virtual function table */
834 for (i = 0; i < c->methodscount; i++) {
835 methodinfo *m = &(c->methods[i]);
837 assert(m->stubroutine == NULL);
839 /* Don't create a compiler stub for abstract methods as they
840 throw an AbstractMethodError with the default stub in the
841 vftbl. This entry is simply copied by sub-classes. */
843 if (m->flags & ACC_ABSTRACT)
846 #if defined(ENABLE_JIT)
847 # if defined(ENABLE_INTRP)
849 m->stubroutine = intrp_createcompilerstub(m);
852 m->stubroutine = codegen_generate_stub_compiler(m);
854 m->stubroutine = intrp_createcompilerstub(m);
857 /* static methods are not in the vftbl */
859 if (m->flags & ACC_STATIC)
862 /* insert the stubroutine into the vftbl */
864 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
866 RT_TIMING_GET_TIME(time_fill_vftbl);
868 /* compute instance size and offset of each field */
870 for (i = 0; i < c->fieldscount; i++) {
872 fieldinfo *f = &(c->fields[i]);
874 if (!(f->flags & ACC_STATIC)) {
875 dsize = descriptor_typesize(f->parseddesc);
877 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
878 /* On i386 and ARM we align double and s8 fields to
879 4-bytes. This matches what GCC does for struct
880 members. We must do the same as gcc here because the
881 offsets in native header structs like java_lang_Double
882 must match the offsets of the Java fields
883 (eg. java.lang.Double.value). */
885 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
887 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
890 f->offset = c->instancesize;
891 c->instancesize += dsize;
894 RT_TIMING_GET_TIME(time_offsets);
896 /* initialize interfacetable and interfacevftbllength */
898 v->interfacevftbllength = MNEW(s4, interfacetablelength);
900 #if defined(ENABLE_STATISTICS)
902 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
905 for (i = 0; i < interfacetablelength; i++) {
906 v->interfacevftbllength[i] = 0;
907 v->interfacetable[-i] = NULL;
912 for (tc = c; tc != NULL; tc = tc->super)
913 for (i = 0; i < tc->interfacescount; i++)
914 if (!linker_addinterface(c, tc->interfaces[i]))
917 RT_TIMING_GET_TIME(time_fill_iftbl);
919 /* add finalizer method (not for java.lang.Object) */
924 fi = class_findmethod(c, utf_finalize, utf_void__void);
927 if (!(fi->flags & ACC_STATIC))
930 RT_TIMING_GET_TIME(time_finalizer);
934 linker_compute_subclasses(c);
936 RT_TIMING_GET_TIME(time_subclasses);
938 /* revert the linking state and class is linked */
940 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
944 /* XXX must this also be done in case of exception? */
946 while (worklist != NULL) {
947 method_worklist *wi = worklist;
949 worklist = worklist->next;
951 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
952 jit_invalidate_code(wi->m);
954 /* XXX put worklist into dump memory? */
955 FREE(wi, method_worklist);
958 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
959 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
960 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
961 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
962 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
963 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
964 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
965 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
966 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
968 /* just return c to show that we didn't had a problem */
974 /* link_array ******************************************************************
976 This function is called by link_class to create the arraydescriptor
979 This function returns NULL if the array cannot be linked because
980 the component type has not been linked yet.
982 *******************************************************************************/
984 static arraydescriptor *link_array(classinfo *c)
988 arraydescriptor *desc;
993 namelen = c->name->blength;
995 /* Check the component type */
997 switch (c->name->text[1]) {
999 /* c is an array of arrays. */
1000 u = utf_new(c->name->text + 1, namelen - 1);
1001 if (!(comp = load_class_from_classloader(u, c->classloader)))
1006 /* c is an array of objects. */
1007 u = utf_new(c->name->text + 2, namelen - 3);
1008 if (!(comp = load_class_from_classloader(u, c->classloader)))
1013 /* If the component type has not been linked, link it now */
1015 assert(!comp || (comp->state & CLASS_LOADED));
1017 if (comp && !(comp->state & CLASS_LINKED))
1018 if (!link_class(comp))
1021 /* Allocate the arraydescriptor */
1023 desc = NEW(arraydescriptor);
1026 /* c is an array of references */
1027 desc->arraytype = ARRAYTYPE_OBJECT;
1028 desc->componentsize = sizeof(void*);
1029 desc->dataoffset = OFFSET(java_objectarray_t, data);
1031 compvftbl = comp->vftbl;
1034 log_text("Component class has no vftbl");
1038 desc->componentvftbl = compvftbl;
1040 if (compvftbl->arraydesc) {
1041 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1043 if (compvftbl->arraydesc->dimension >= 255) {
1044 log_text("Creating array of dimension >255");
1048 desc->dimension = compvftbl->arraydesc->dimension + 1;
1049 desc->elementtype = compvftbl->arraydesc->elementtype;
1052 desc->elementvftbl = compvftbl;
1053 desc->dimension = 1;
1054 desc->elementtype = ARRAYTYPE_OBJECT;
1058 /* c is an array of a primitive type */
1059 switch (c->name->text[1]) {
1061 desc->arraytype = ARRAYTYPE_BOOLEAN;
1062 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1063 desc->componentsize = sizeof(u1);
1067 desc->arraytype = ARRAYTYPE_BYTE;
1068 desc->dataoffset = OFFSET(java_bytearray_t,data);
1069 desc->componentsize = sizeof(u1);
1073 desc->arraytype = ARRAYTYPE_CHAR;
1074 desc->dataoffset = OFFSET(java_chararray_t,data);
1075 desc->componentsize = sizeof(u2);
1079 desc->arraytype = ARRAYTYPE_DOUBLE;
1080 desc->dataoffset = OFFSET(java_doublearray_t,data);
1081 desc->componentsize = sizeof(double);
1085 desc->arraytype = ARRAYTYPE_FLOAT;
1086 desc->dataoffset = OFFSET(java_floatarray_t,data);
1087 desc->componentsize = sizeof(float);
1091 desc->arraytype = ARRAYTYPE_INT;
1092 desc->dataoffset = OFFSET(java_intarray_t,data);
1093 desc->componentsize = sizeof(s4);
1097 desc->arraytype = ARRAYTYPE_LONG;
1098 desc->dataoffset = OFFSET(java_longarray_t,data);
1099 desc->componentsize = sizeof(s8);
1103 desc->arraytype = ARRAYTYPE_SHORT;
1104 desc->dataoffset = OFFSET(java_shortarray_t,data);
1105 desc->componentsize = sizeof(s2);
1109 exceptions_throw_noclassdeffounderror(c->name);
1113 desc->componentvftbl = NULL;
1114 desc->elementvftbl = NULL;
1115 desc->dimension = 1;
1116 desc->elementtype = desc->arraytype;
1123 /* linker_compute_subclasses ***************************************************
1127 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1128 This function needs to take the class renumber lock and stop the
1129 world during class renumbering. The lock is used in C code which
1130 is not that performance critical. Whereas JIT code uses critical
1131 sections to atomically access the class values.
1133 *******************************************************************************/
1135 static void linker_compute_subclasses(classinfo *c)
1137 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1139 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1140 threads_stopworld();
1143 if (!(c->flags & ACC_INTERFACE)) {
1148 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1149 c->nextsub = c->super->sub;
1155 /* compute class values */
1157 linker_compute_class_values(class_java_lang_Object);
1159 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1161 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1162 threads_startworld();
1167 /* linker_compute_class_values *************************************************
1171 *******************************************************************************/
1173 static void linker_compute_class_values(classinfo *c)
1177 c->vftbl->baseval = ++classvalue;
1182 linker_compute_class_values(subs);
1184 subs = subs->nextsub;
1187 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1191 /* linker_addinterface *********************************************************
1193 Is needed by link_class for adding a VTBL to a class. All
1194 interfaces implemented by ic are added as well.
1197 true.........everything ok
1198 false........an exception has been thrown
1200 *******************************************************************************/
1202 static bool linker_addinterface(classinfo *c, classinfo *ic)
1213 if (i >= v->interfacetablelength)
1214 vm_abort("Internal error: interfacetable overflow");
1216 /* if this interface has already been added, return immediately */
1218 if (v->interfacetable[-i] != NULL)
1221 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1222 v->interfacevftbllength[i] = 1;
1223 v->interfacetable[-i] = MNEW(methodptr, 1);
1224 v->interfacetable[-i][0] = NULL;
1227 v->interfacevftbllength[i] = ic->methodscount;
1228 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1230 #if defined(ENABLE_STATISTICS)
1232 count_vftbl_len += sizeof(methodptr) *
1233 (ic->methodscount + (ic->methodscount == 0));
1236 for (j = 0; j < ic->methodscount; j++) {
1237 for (sc = c; sc != NULL; sc = sc->super) {
1238 for (k = 0; k < sc->methodscount; k++) {
1239 m = &(sc->methods[k]);
1241 if (method_canoverwrite(m, &(ic->methods[j]))) {
1242 /* method m overwrites the (abstract) method */
1243 #if defined(ENABLE_VERIFIER)
1244 /* Add loading constraints (for the more
1245 general types of the method
1247 if (!classcache_add_constraints_for_params(
1248 c->classloader, ic->classloader,
1255 /* XXX taken from gcj */
1256 /* check for ACC_STATIC: IncompatibleClassChangeError */
1258 /* check for !ACC_PUBLIC: IllegalAccessError */
1260 /* check for ACC_ABSTRACT: AbstracMethodError,
1261 not sure about that one */
1263 v->interfacetable[-i][j] = v->table[m->vftblindex];
1269 /* If no method was found, insert the AbstractMethodError
1272 #if defined(ENABLE_JIT)
1273 # if defined(ENABLE_INTRP)
1275 v->interfacetable[-i][j] =
1276 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1279 v->interfacetable[-i][j] =
1280 (methodptr) (ptrint) &asm_abstractmethoderror;
1282 v->interfacetable[-i][j] =
1283 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1291 /* add superinterfaces of this interface */
1293 for (j = 0; j < ic->interfacescount; j++)
1294 if (!linker_addinterface(c, ic->interfaces[j]))
1303 /* class_highestinterface ******************************************************
1305 Used by the function link_class to determine the amount of memory
1306 needed for the interface table.
1308 *******************************************************************************/
1310 static s4 class_highestinterface(classinfo *c)
1316 /* check for ACC_INTERFACE bit already done in link_class_intern */
1320 for (i = 0; i < c->interfacescount; i++) {
1321 h2 = class_highestinterface(c->interfaces[i]);
1332 * These are local overrides for various environment variables in Emacs.
1333 * Please do not remove this and leave it at the end of the file, where
1334 * Emacs will automagically detect them.
1335 * ---------------------------------------------------------------------
1338 * indent-tabs-mode: t
1342 * vim:noexpandtab:sw=4:ts=4: