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"
58 /* #include "vm/resolve.h" */
59 /* copied prototype to avoid bootstrapping problem: */
60 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
62 #if defined(ENABLE_STATISTICS)
63 # include "vmcore/statistics.h"
66 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
67 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
69 #define INLINELOG(code)
73 /* global variables ***********************************************************/
75 static s4 interfaceindex; /* sequential numbering of interfaces */
78 java_object_t *linker_classrenumber_lock;
81 /* private functions **********************************************************/
83 static classinfo *link_class_intern(classinfo *c);
84 static arraydescriptor *link_array(classinfo *c);
85 static void linker_compute_class_values(classinfo *c);
86 static void linker_compute_subclasses(classinfo *c);
87 static bool linker_addinterface(classinfo *c, classinfo *ic);
88 static s4 class_highestinterface(classinfo *c);
91 /* dummy structures for alinment checks ***************************************/
93 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
94 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
96 struct dummy_alignment_long_t {
101 struct dummy_alignment_double_t {
107 /* linker_init *****************************************************************
109 Initializes the linker subsystem and links classes required for the
112 *******************************************************************************/
114 void linker_preinit(void)
116 /* Check for if alignment for long and double matches what we
117 assume for the current architecture. */
119 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
120 if (OFFSET(dummy_alignment_long_t, l) != 4)
121 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
122 OFFSET(dummy_alignment_long_t, l), 4);
124 if (OFFSET(dummy_alignment_double_t, d) != 4)
125 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
126 OFFSET(dummy_alignment_double_t, d), 4);
128 if (OFFSET(dummy_alignment_long_t, l) != 8)
129 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
130 OFFSET(dummy_alignment_long_t, l), 8);
132 if (OFFSET(dummy_alignment_double_t, d) != 8)
133 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
134 OFFSET(dummy_alignment_double_t, d), 8);
137 /* Reset interface index. */
141 #if defined(ENABLE_THREADS)
142 /* create the global lock object */
144 linker_classrenumber_lock = NEW(java_object_t);
146 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
149 /* Link the most basic classes. */
151 if (!link_class(class_java_lang_Object))
152 vm_abort("linker_preinit: linking java/lang/Object failed");
154 #if defined(ENABLE_JAVASE)
155 if (!link_class(class_java_lang_Cloneable))
156 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
158 if (!link_class(class_java_io_Serializable))
159 vm_abort("linker_preinit: linking java/io/Serializable failed");
164 /* linker_init *****************************************************************
166 Links all classes required in the VM.
168 *******************************************************************************/
170 void linker_init(void)
172 /* Link java.lang.Class as first class of the system, because we
173 need it's vftbl for all other classes so we can use a class as
176 if (!link_class(class_java_lang_Class))
177 vm_abort("linker_init: linking java/lang/Class failed");
179 /* Now set the header.vftbl of all classes which were created
180 before java.lang.Class was linked. */
182 class_postset_header_vftbl();
184 /* Link primitive-type wrapping classes. */
186 #if defined(ENABLE_JAVASE)
187 if (!link_class(class_java_lang_Void))
188 vm_abort("linker_init: linking failed");
191 if (!link_class(class_java_lang_Boolean))
192 vm_abort("linker_init: linking failed");
194 if (!link_class(class_java_lang_Byte))
195 vm_abort("linker_init: linking failed");
197 if (!link_class(class_java_lang_Character))
198 vm_abort("linker_init: linking failed");
200 if (!link_class(class_java_lang_Short))
201 vm_abort("linker_init: linking failed");
203 if (!link_class(class_java_lang_Integer))
204 vm_abort("linker_init: linking failed");
206 if (!link_class(class_java_lang_Long))
207 vm_abort("linker_init: linking failed");
209 if (!link_class(class_java_lang_Float))
210 vm_abort("linker_init: linking failed");
212 if (!link_class(class_java_lang_Double))
213 vm_abort("linker_init: linking failed");
215 /* Link important system classes. */
217 if (!link_class(class_java_lang_String))
218 vm_abort("linker_init: linking java/lang/String failed");
220 #if defined(ENABLE_JAVASE)
221 if (!link_class(class_java_lang_ClassLoader))
222 vm_abort("linker_init: linking failed");
224 if (!link_class(class_java_lang_SecurityManager))
225 vm_abort("linker_init: linking failed");
228 if (!link_class(class_java_lang_System))
229 vm_abort("linker_init: linking failed");
231 if (!link_class(class_java_lang_Thread))
232 vm_abort("linker_init: linking failed");
234 #if defined(ENABLE_JAVASE)
235 if (!link_class(class_java_lang_ThreadGroup))
236 vm_abort("linker_init: linking failed");
239 #if defined(WITH_CLASSPATH_GNU)
240 if (!link_class(class_java_lang_VMSystem))
241 vm_abort("linker_init: linking failed");
243 if (!link_class(class_java_lang_VMThread))
244 vm_abort("linker_init: linking failed");
248 /* some classes which may be used more often */
250 #if defined(ENABLE_JAVASE)
251 if (!link_class(class_java_lang_StackTraceElement))
252 vm_abort("linker_init: linking failed");
254 if (!link_class(class_java_lang_reflect_Constructor))
255 vm_abort("linker_init: linking failed");
257 if (!link_class(class_java_lang_reflect_Field))
258 vm_abort("linker_init: linking failed");
260 if (!link_class(class_java_lang_reflect_Method))
261 vm_abort("linker_init: linking failed");
263 if (!link_class(class_java_security_PrivilegedAction))
264 vm_abort("linker_init: linking failed");
266 if (!link_class(class_java_util_Vector))
267 vm_abort("linker_init: linking failed");
269 # if defined(WITH_CLASSPATH_SUN)
270 if (!link_class(class_sun_reflect_MagicAccessorImpl))
271 vm_abort("linker_init: linking failed");
274 if (!link_class(arrayclass_java_lang_Object))
275 vm_abort("linker_init: linking failed");
279 /* create pseudo classes used by the typechecker */
281 /* pseudo class for Arraystubs (extends java.lang.Object) */
283 pseudo_class_Arraystub =
284 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
285 pseudo_class_Arraystub->state |= CLASS_LOADED;
286 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
288 #if defined(ENABLE_JAVASE)
290 pseudo_class_Arraystub->interfacescount = 2;
291 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
292 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
293 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
295 #elif defined(ENABLE_JAVAME_CLDC1_1)
297 pseudo_class_Arraystub->interfacescount = 0;
298 pseudo_class_Arraystub->interfaces = NULL;
301 # error unknown Java configuration
304 if (!classcache_store_unique(pseudo_class_Arraystub))
305 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
307 if (!link_class(pseudo_class_Arraystub))
308 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
310 /* pseudo class representing the null type */
312 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
313 pseudo_class_Null->state |= CLASS_LOADED;
314 pseudo_class_Null->super.cls = class_java_lang_Object;
316 if (!classcache_store_unique(pseudo_class_Null))
317 vm_abort("linker_init: could not cache pseudo_class_Null");
319 if (!link_class(pseudo_class_Null))
320 vm_abort("linker_init: linking failed");
322 /* pseudo class representing new uninitialized objects */
324 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
325 pseudo_class_New->state |= CLASS_LOADED;
326 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
327 pseudo_class_New->super.cls = class_java_lang_Object;
329 if (!classcache_store_unique(pseudo_class_New))
330 vm_abort("linker_init: could not cache pseudo_class_New");
332 /* Correct vftbl-entries (retarded loading and linking of class
333 java/lang/String). */
335 stringtable_update();
339 /* link_class ******************************************************************
341 Wrapper function for link_class_intern to ease monitor enter/exit
342 and exception handling.
344 *******************************************************************************/
346 classinfo *link_class(classinfo *c)
349 #if defined(ENABLE_RT_TIMING)
350 struct timespec time_start, time_end;
353 RT_TIMING_GET_TIME(time_start);
356 exceptions_throw_nullpointerexception();
360 LOCK_MONITOR_ENTER(c);
362 /* Maybe the class is currently linking or is already linked.*/
364 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
365 LOCK_MONITOR_EXIT(c);
370 #if defined(ENABLE_STATISTICS)
373 if (opt_getcompilingtime)
374 compilingtime_stop();
376 if (opt_getloadingtime)
380 /* call the internal function */
382 r = link_class_intern(c);
384 /* If return value is NULL, we had a problem and the class is not
388 c->state &= ~CLASS_LINKING;
390 #if defined(ENABLE_STATISTICS)
393 if (opt_getloadingtime)
396 if (opt_getcompilingtime)
397 compilingtime_start();
400 LOCK_MONITOR_EXIT(c);
402 RT_TIMING_GET_TIME(time_end);
404 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
410 /* linker_overwrite_method *****************************************************
412 Overwrite a method with another one, update method flags and check
416 mg................the general method being overwritten
417 ms................the overwriting (more specialized) method
418 wl................worklist where to add invalidated methods
421 true..............everything ok
422 false.............an exception has been thrown
424 *******************************************************************************/
426 static bool linker_overwrite_method(methodinfo *mg,
428 method_worklist **wl)
436 /* overriding a final method is illegal */
438 if (mg->flags & ACC_FINAL) {
439 exceptions_throw_verifyerror(mg, "Overriding final method");
443 /* method ms overwrites method mg */
445 #if defined(ENABLE_VERIFIER)
446 /* Add loading constraints (for the more general types of method mg). */
447 /* Not for <init>, as it is not invoked virtually. */
449 if ((ms->name != utf_init)
450 && !classcache_add_constraints_for_params(
451 cs->classloader, cg->classloader, mg))
457 /* inherit the vftbl index, and record the overwriting */
459 ms->vftblindex = mg->vftblindex;
462 /* update flags and check assumptions */
463 /* <init> methods are a special case, as they are never dispatched dynamically */
465 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
467 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
468 /* this adds another implementation */
470 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
472 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
474 method_break_assumption_monomorphic(mg, wl);
477 /* this is the first implementation */
479 mg->flags |= ACC_METHOD_IMPLEMENTED;
481 INLINELOG( printf("becomes implemented: "); method_println(mg); );
486 } while (mg != NULL);
493 /* link_class_intern ***********************************************************
495 Tries to link a class. The function calculates the length in bytes
496 that an instance of this class requires as well as the VTBL for
497 methods and interface methods.
499 *******************************************************************************/
501 static classinfo *link_class_intern(classinfo *c)
503 classinfo *super; /* super class */
504 classinfo *tc; /* temporary class variable */
505 s4 supervftbllength; /* vftbllegnth of super class */
506 s4 vftbllength; /* vftbllength of current class */
507 s4 interfacetablelength; /* interface table length */
508 vftbl_t *v; /* vftbl of current class */
509 s4 i; /* interface/method/field counter */
510 arraydescriptor *arraydesc; /* descriptor for array classes */
511 method_worklist *worklist; /* worklist for recompilation */
512 #if defined(ENABLE_RT_TIMING)
513 struct timespec time_start, time_resolving, time_compute_vftbl,
514 time_abstract, time_compute_iftbl, time_fill_vftbl,
515 time_offsets, time_fill_iftbl, time_finalizer,
519 RT_TIMING_GET_TIME(time_start);
523 log_message_class("Linking class: ", c);
526 /* the class must be loaded */
528 /* XXX should this be a specific exception? */
529 assert(c->state & CLASS_LOADED);
531 /* This is check in link_class. */
533 assert(!(c->state & CLASS_LINKED));
535 /* cache the self-reference of this class */
536 /* we do this for cases where the defining loader of the class */
537 /* has not yet been recorded as an initiating loader for the class */
538 /* this is needed so subsequent code can assume that self-refs */
539 /* will always resolve lazily */
540 /* No need to do it for the bootloader - it is always registered */
541 /* as initiating loader for the classes it loads. */
543 classcache_store(c->classloader,c,false);
545 /* this class is currently linking */
547 c->state |= CLASS_LINKING;
552 /* check interfaces */
554 for (i = 0; i < c->interfacescount; i++) {
555 /* resolve this super interface */
557 if ((tc = resolve_classref_or_classinfo_eager(c->interfaces[i], true)) == NULL)
560 c->interfaces[i].cls = tc;
562 /* detect circularity */
565 exceptions_throw_classcircularityerror(c);
569 assert(tc->state & CLASS_LOADED);
571 if (!(tc->flags & ACC_INTERFACE)) {
572 exceptions_throw_incompatibleclasschangeerror(tc,
573 "Implementing class");
577 if (!(tc->state & CLASS_LINKED))
582 /* check super class */
586 if (c->super.any == NULL) { /* class java.lang.Object */
588 c->instancesize = sizeof(java_object_t);
590 vftbllength = supervftbllength = 0;
596 /* Resolve super class. */
598 super = resolve_classref_or_classinfo_eager(c->super, true);
603 c->super.cls = super;
605 /* Detect circularity. */
608 exceptions_throw_classcircularityerror(c);
612 assert(super->state & CLASS_LOADED);
614 if (super->flags & ACC_INTERFACE) {
615 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
616 log_text("Interface specified as super class");
620 /* Don't allow extending final classes */
622 if (super->flags & ACC_FINAL) {
623 exceptions_throw_verifyerror(NULL,
624 "Cannot inherit from final class");
628 /* link the superclass if necessary */
630 if (!(super->state & CLASS_LINKED))
631 if (!link_class(super))
634 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
637 c->flags |= (super->flags &
638 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
640 /* handle array classes */
642 if (c->name->text[0] == '[')
643 if (!(arraydesc = link_array(c)))
646 if (c->flags & ACC_INTERFACE)
647 c->index = interfaceindex++;
649 c->index = super->index + 1;
651 c->instancesize = super->instancesize;
653 vftbllength = supervftbllength = super->vftbl->vftbllength;
655 c->finalizer = super->finalizer;
657 RT_TIMING_GET_TIME(time_resolving);
660 /* compute vftbl length */
662 for (i = 0; i < c->methodscount; i++) {
663 methodinfo *m = &(c->methods[i]);
665 if (!(m->flags & ACC_STATIC)) { /* is instance method */
671 for (j = 0; j < tc->methodscount; j++) {
672 if (method_canoverwrite(m, &(tc->methods[j]))) {
673 if (tc->methods[j].flags & ACC_PRIVATE)
674 goto notfoundvftblindex;
676 /* package-private methods in other packages */
677 /* must not be overridden */
678 /* (see Java Language Specification 8.4.8.1) */
679 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
680 && !SAME_PACKAGE(c,tc) )
682 goto notfoundvftblindex;
685 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
688 goto foundvftblindex;
696 m->vftblindex = (vftbllength++);
701 RT_TIMING_GET_TIME(time_compute_vftbl);
704 /* Check all interfaces of an abstract class (maybe be an
705 interface too) for unimplemented methods. Such methods are
706 called miranda-methods and are marked with the ACC_MIRANDA
707 flag. VMClass.getDeclaredMethods does not return such
710 if (c->flags & ACC_ABSTRACT) {
713 s4 abstractmethodscount;
717 abstractmethodscount = 0;
719 /* check all interfaces of the abstract class */
721 for (i = 0; i < c->interfacescount; i++) {
722 ic = c->interfaces[i].cls;
724 for (j = 0; j < ic->methodscount; j++) {
725 im = &(ic->methods[j]);
727 /* skip `<clinit>' and `<init>' */
729 if ((im->name == utf_clinit) || (im->name == utf_init))
732 for (tc = c; tc != NULL; tc = tc->super.cls) {
733 for (k = 0; k < tc->methodscount; k++) {
734 if (method_canoverwrite(im, &(tc->methods[k])))
735 goto noabstractmethod;
739 abstractmethodscount++;
746 if (abstractmethodscount > 0) {
749 /* reallocate methods memory */
751 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
752 c->methodscount + abstractmethodscount);
754 for (i = 0; i < c->interfacescount; i++) {
755 ic = c->interfaces[i].cls;
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.cls) {
766 for (k = 0; k < tc->methodscount; k++) {
767 if (method_canoverwrite(im, &(tc->methods[k])))
768 goto noabstractmethod2;
772 /* Copy the method found into the new c->methods
773 array and tag it as miranda-method. */
775 am = &(c->methods[c->methodscount]);
778 MCOPY(am, im, methodinfo, 1);
780 am->vftblindex = (vftbllength++);
782 am->flags |= ACC_MIRANDA;
790 RT_TIMING_GET_TIME(time_abstract);
793 #if defined(ENABLE_STATISTICS)
796 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
799 /* compute interfacetable length */
801 interfacetablelength = 0;
803 for (tc = c; tc != NULL; tc = tc->super.cls) {
804 for (i = 0; i < tc->interfacescount; i++) {
805 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
807 if (h > interfacetablelength)
808 interfacetablelength = h;
811 RT_TIMING_GET_TIME(time_compute_iftbl);
813 /* allocate virtual function table */
815 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
816 sizeof(methodptr) * (vftbllength - 1) +
817 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
818 v = (vftbl_t *) (((methodptr *) v) +
819 (interfacetablelength - 1) * (interfacetablelength > 1));
823 v->vftbllength = vftbllength;
824 v->interfacetablelength = interfacetablelength;
825 v->arraydesc = arraydesc;
827 /* store interface index in vftbl */
829 if (c->flags & ACC_INTERFACE)
830 v->baseval = -(c->index);
832 /* copy virtual function table of super class */
834 for (i = 0; i < supervftbllength; i++)
835 v->table[i] = super->vftbl->table[i];
837 /* Fill the remaining vftbl slots with the AbstractMethodError
838 stub (all after the super class slots, because they are already
841 for (; i < vftbllength; i++) {
842 #if defined(ENABLE_JIT)
843 # if defined(ENABLE_INTRP)
845 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
848 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
850 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
854 /* add method stubs into virtual function table */
856 for (i = 0; i < c->methodscount; i++) {
857 methodinfo *m = &(c->methods[i]);
859 assert(m->stubroutine == NULL);
861 /* Don't create a compiler stub for abstract methods as they
862 throw an AbstractMethodError with the default stub in the
863 vftbl. This entry is simply copied by sub-classes. */
865 if (m->flags & ACC_ABSTRACT)
868 #if defined(ENABLE_JIT)
869 # if defined(ENABLE_INTRP)
871 m->stubroutine = intrp_createcompilerstub(m);
874 m->stubroutine = codegen_generate_stub_compiler(m);
876 m->stubroutine = intrp_createcompilerstub(m);
879 /* static methods are not in the vftbl */
881 if (m->flags & ACC_STATIC)
884 /* insert the stubroutine into the vftbl */
886 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
888 RT_TIMING_GET_TIME(time_fill_vftbl);
890 /* compute instance size and offset of each field */
892 for (i = 0; i < c->fieldscount; i++) {
894 fieldinfo *f = &(c->fields[i]);
896 if (!(f->flags & ACC_STATIC)) {
897 dsize = descriptor_typesize(f->parseddesc);
899 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
900 /* On i386 and ARM we align double and s8 fields to
901 4-bytes. This matches what GCC does for struct
902 members. We must do the same as gcc here because the
903 offsets in native header structs like java_lang_Double
904 must match the offsets of the Java fields
905 (eg. java.lang.Double.value). */
907 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
909 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
912 f->offset = c->instancesize;
913 c->instancesize += dsize;
916 RT_TIMING_GET_TIME(time_offsets);
918 /* initialize interfacetable and interfacevftbllength */
920 v->interfacevftbllength = MNEW(s4, interfacetablelength);
922 #if defined(ENABLE_STATISTICS)
924 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
927 for (i = 0; i < interfacetablelength; i++) {
928 v->interfacevftbllength[i] = 0;
929 v->interfacetable[-i] = NULL;
934 for (tc = c; tc != NULL; tc = tc->super.cls)
935 for (i = 0; i < tc->interfacescount; i++)
936 if (!linker_addinterface(c, tc->interfaces[i].cls))
939 RT_TIMING_GET_TIME(time_fill_iftbl);
941 /* add finalizer method (not for java.lang.Object) */
946 fi = class_findmethod(c, utf_finalize, utf_void__void);
949 if (!(fi->flags & ACC_STATIC))
952 RT_TIMING_GET_TIME(time_finalizer);
956 linker_compute_subclasses(c);
958 RT_TIMING_GET_TIME(time_subclasses);
960 /* revert the linking state and class is linked */
962 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
966 /* XXX must this also be done in case of exception? */
968 while (worklist != NULL) {
969 method_worklist *wi = worklist;
971 worklist = worklist->next;
973 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
974 jit_invalidate_code(wi->m);
976 /* XXX put worklist into dump memory? */
977 FREE(wi, method_worklist);
982 log_message_class("Linking done class: ", c);
985 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
986 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
987 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
988 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
989 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
990 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
991 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
992 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
993 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
995 /* just return c to show that we didn't had a problem */
1001 /* link_array ******************************************************************
1003 This function is called by link_class to create the arraydescriptor
1006 This function returns NULL if the array cannot be linked because
1007 the component type has not been linked yet.
1009 *******************************************************************************/
1011 static arraydescriptor *link_array(classinfo *c)
1015 arraydescriptor *desc;
1020 namelen = c->name->blength;
1022 /* Check the component type */
1024 switch (c->name->text[1]) {
1026 /* c is an array of arrays. */
1027 u = utf_new(c->name->text + 1, namelen - 1);
1028 if (!(comp = load_class_from_classloader(u, c->classloader)))
1033 /* c is an array of objects. */
1034 u = utf_new(c->name->text + 2, namelen - 3);
1035 if (!(comp = load_class_from_classloader(u, c->classloader)))
1040 /* If the component type has not been linked, link it now */
1042 assert(!comp || (comp->state & CLASS_LOADED));
1044 if (comp && !(comp->state & CLASS_LINKED))
1045 if (!link_class(comp))
1048 /* Allocate the arraydescriptor */
1050 desc = NEW(arraydescriptor);
1053 /* c is an array of references */
1054 desc->arraytype = ARRAYTYPE_OBJECT;
1055 desc->componentsize = sizeof(void*);
1056 desc->dataoffset = OFFSET(java_objectarray_t, data);
1058 compvftbl = comp->vftbl;
1061 log_text("Component class has no vftbl");
1065 desc->componentvftbl = compvftbl;
1067 if (compvftbl->arraydesc) {
1068 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1070 if (compvftbl->arraydesc->dimension >= 255) {
1071 log_text("Creating array of dimension >255");
1075 desc->dimension = compvftbl->arraydesc->dimension + 1;
1076 desc->elementtype = compvftbl->arraydesc->elementtype;
1079 desc->elementvftbl = compvftbl;
1080 desc->dimension = 1;
1081 desc->elementtype = ARRAYTYPE_OBJECT;
1085 /* c is an array of a primitive type */
1086 switch (c->name->text[1]) {
1088 desc->arraytype = ARRAYTYPE_BOOLEAN;
1089 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1090 desc->componentsize = sizeof(u1);
1094 desc->arraytype = ARRAYTYPE_BYTE;
1095 desc->dataoffset = OFFSET(java_bytearray_t,data);
1096 desc->componentsize = sizeof(u1);
1100 desc->arraytype = ARRAYTYPE_CHAR;
1101 desc->dataoffset = OFFSET(java_chararray_t,data);
1102 desc->componentsize = sizeof(u2);
1106 desc->arraytype = ARRAYTYPE_DOUBLE;
1107 desc->dataoffset = OFFSET(java_doublearray_t,data);
1108 desc->componentsize = sizeof(double);
1112 desc->arraytype = ARRAYTYPE_FLOAT;
1113 desc->dataoffset = OFFSET(java_floatarray_t,data);
1114 desc->componentsize = sizeof(float);
1118 desc->arraytype = ARRAYTYPE_INT;
1119 desc->dataoffset = OFFSET(java_intarray_t,data);
1120 desc->componentsize = sizeof(s4);
1124 desc->arraytype = ARRAYTYPE_LONG;
1125 desc->dataoffset = OFFSET(java_longarray_t,data);
1126 desc->componentsize = sizeof(s8);
1130 desc->arraytype = ARRAYTYPE_SHORT;
1131 desc->dataoffset = OFFSET(java_shortarray_t,data);
1132 desc->componentsize = sizeof(s2);
1136 exceptions_throw_noclassdeffounderror(c->name);
1140 desc->componentvftbl = NULL;
1141 desc->elementvftbl = NULL;
1142 desc->dimension = 1;
1143 desc->elementtype = desc->arraytype;
1150 /* linker_compute_subclasses ***************************************************
1154 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1155 This function needs to take the class renumber lock and stop the
1156 world during class renumbering. The lock is used in C code which
1157 is not that performance critical. Whereas JIT code uses critical
1158 sections to atomically access the class values.
1160 *******************************************************************************/
1162 static void linker_compute_subclasses(classinfo *c)
1164 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1166 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1167 threads_stopworld();
1170 if (!(c->flags & ACC_INTERFACE)) {
1175 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1176 c->nextsub = c->super.cls->sub;
1177 c->super.cls->sub = c;
1182 /* compute class values */
1184 linker_compute_class_values(class_java_lang_Object);
1186 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1188 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1189 threads_startworld();
1194 /* linker_compute_class_values *************************************************
1198 *******************************************************************************/
1200 static void linker_compute_class_values(classinfo *c)
1204 c->vftbl->baseval = ++classvalue;
1209 linker_compute_class_values(subs);
1211 subs = subs->nextsub;
1214 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1218 /* linker_addinterface *********************************************************
1220 Is needed by link_class for adding a VTBL to a class. All
1221 interfaces implemented by ic are added as well.
1224 true.........everything ok
1225 false........an exception has been thrown
1227 *******************************************************************************/
1229 static bool linker_addinterface(classinfo *c, classinfo *ic)
1240 if (i >= v->interfacetablelength)
1241 vm_abort("Internal error: interfacetable overflow");
1243 /* if this interface has already been added, return immediately */
1245 if (v->interfacetable[-i] != NULL)
1248 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1249 v->interfacevftbllength[i] = 1;
1250 v->interfacetable[-i] = MNEW(methodptr, 1);
1251 v->interfacetable[-i][0] = NULL;
1254 v->interfacevftbllength[i] = ic->methodscount;
1255 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1257 #if defined(ENABLE_STATISTICS)
1259 count_vftbl_len += sizeof(methodptr) *
1260 (ic->methodscount + (ic->methodscount == 0));
1263 for (j = 0; j < ic->methodscount; j++) {
1264 for (sc = c; sc != NULL; sc = sc->super.cls) {
1265 for (k = 0; k < sc->methodscount; k++) {
1266 m = &(sc->methods[k]);
1268 if (method_canoverwrite(m, &(ic->methods[j]))) {
1269 /* method m overwrites the (abstract) method */
1270 #if defined(ENABLE_VERIFIER)
1271 /* Add loading constraints (for the more
1272 general types of the method
1274 if (!classcache_add_constraints_for_params(
1275 c->classloader, ic->classloader,
1282 /* XXX taken from gcj */
1283 /* check for ACC_STATIC: IncompatibleClassChangeError */
1285 /* check for !ACC_PUBLIC: IllegalAccessError */
1287 /* check for ACC_ABSTRACT: AbstracMethodError,
1288 not sure about that one */
1290 v->interfacetable[-i][j] = v->table[m->vftblindex];
1296 /* If no method was found, insert the AbstractMethodError
1299 #if defined(ENABLE_JIT)
1300 # if defined(ENABLE_INTRP)
1302 v->interfacetable[-i][j] =
1303 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1306 v->interfacetable[-i][j] =
1307 (methodptr) (ptrint) &asm_abstractmethoderror;
1309 v->interfacetable[-i][j] =
1310 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1318 /* add superinterfaces of this interface */
1320 for (j = 0; j < ic->interfacescount; j++)
1321 if (!linker_addinterface(c, ic->interfaces[j].cls))
1330 /* class_highestinterface ******************************************************
1332 Used by the function link_class to determine the amount of memory
1333 needed for the interface table.
1335 *******************************************************************************/
1337 static s4 class_highestinterface(classinfo *c)
1343 /* check for ACC_INTERFACE bit already done in link_class_intern */
1347 for (i = 0; i < c->interfacescount; i++) {
1348 h2 = class_highestinterface(c->interfaces[i].cls);
1359 * These are local overrides for various environment variables in Emacs.
1360 * Please do not remove this and leave it at the end of the file, where
1361 * Emacs will automagically detect them.
1362 * ---------------------------------------------------------------------
1365 * indent-tabs-mode: t
1369 * vim:noexpandtab:sw=4:ts=4: