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
25 $Id: linker.c 8350 2007-08-19 17:06:20Z twisti $
36 #include "mm/memory.h"
38 #include "native/native.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/logging.h"
44 #include "vm/access.h"
46 #include "vm/exceptions.h"
47 #include "vm/primitive.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit_interface.h"
53 #include "vmcore/class.h"
54 #include "vmcore/classcache.h"
55 #include "vmcore/loader.h"
56 #include "vmcore/options.h"
57 #include "vmcore/rt-timing.h"
59 /* #include "vm/resolve.h" */
60 /* copied prototype to avoid bootstrapping problem: */
61 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
63 #if defined(ENABLE_STATISTICS)
64 # include "vmcore/statistics.h"
67 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
68 #define INLINELOG(code) do { if (opt_inline_debug_log) { code } } while (0)
70 #define INLINELOG(code)
74 /* global variables ***********************************************************/
76 static s4 interfaceindex; /* sequential numbering of interfaces */
79 java_object_t *linker_classrenumber_lock;
82 /* private functions **********************************************************/
84 static classinfo *link_class_intern(classinfo *c);
85 static arraydescriptor *link_array(classinfo *c);
86 static void linker_compute_class_values(classinfo *c);
87 static void linker_compute_subclasses(classinfo *c);
88 static bool linker_addinterface(classinfo *c, classinfo *ic);
89 static s4 class_highestinterface(classinfo *c);
92 /* dummy structures for alinment checks ***************************************/
94 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
95 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
97 struct dummy_alignment_long_t {
102 struct dummy_alignment_double_t {
108 /* linker_init *****************************************************************
110 Initializes the linker subsystem.
112 *******************************************************************************/
114 bool linker_init(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_init: 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_init: 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_init: 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_init: 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 java.lang.Class as first class of the system, because we
150 need it's vftbl for all other classes so we can use a class as
153 if (!link_class(class_java_lang_Class))
156 /* now set the header.vftbl of all classes which were created
157 before java.lang.Class was linked */
159 class_postset_header_vftbl();
162 /* link important system classes */
164 if (!link_class(class_java_lang_Object))
167 if (!link_class(class_java_lang_String))
170 #if defined(ENABLE_JAVASE)
171 if (!link_class(class_java_lang_Cloneable))
174 if (!link_class(class_java_io_Serializable))
178 /* link classes for wrapping primitive types */
180 #if defined(ENABLE_JAVASE)
181 if (!link_class(class_java_lang_Void))
185 if (!link_class(class_java_lang_Boolean))
188 if (!link_class(class_java_lang_Byte))
191 if (!link_class(class_java_lang_Character))
194 if (!link_class(class_java_lang_Short))
197 if (!link_class(class_java_lang_Integer))
200 if (!link_class(class_java_lang_Long))
203 if (!link_class(class_java_lang_Float))
206 if (!link_class(class_java_lang_Double))
210 /* load some other important classes */
212 #if defined(ENABLE_JAVASE)
213 if (!link_class(class_java_lang_ClassLoader))
216 if (!link_class(class_java_lang_SecurityManager))
220 if (!link_class(class_java_lang_System))
223 if (!link_class(class_java_lang_Thread))
226 #if defined(ENABLE_JAVASE)
227 if (!link_class(class_java_lang_ThreadGroup))
231 #if defined(WITH_CLASSPATH_GNU)
232 if (!link_class(class_java_lang_VMSystem))
235 if (!link_class(class_java_lang_VMThread))
240 /* some classes which may be used more often */
242 #if defined(ENABLE_JAVASE)
243 if (!link_class(class_java_lang_StackTraceElement))
246 if (!link_class(class_java_lang_reflect_Constructor))
249 if (!link_class(class_java_lang_reflect_Field))
252 if (!link_class(class_java_lang_reflect_Method))
255 if (!link_class(class_java_security_PrivilegedAction))
258 if (!link_class(class_java_util_Vector))
261 # if defined(WITH_CLASSPATH_SUN)
262 if (!link_class(class_sun_reflect_MagicAccessorImpl))
266 if (!link_class(arrayclass_java_lang_Object))
271 /* create pseudo classes used by the typechecker */
273 /* pseudo class for Arraystubs (extends java.lang.Object) */
275 pseudo_class_Arraystub =
276 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
277 pseudo_class_Arraystub->state |= CLASS_LOADED;
278 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
280 #if defined(ENABLE_JAVASE)
281 pseudo_class_Arraystub->interfacescount = 2;
282 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
283 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
284 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
285 #elif defined(ENABLE_JAVAME_CLDC1_1)
286 pseudo_class_Arraystub->interfacescount = 0;
287 pseudo_class_Arraystub->interfaces = NULL;
290 if (!classcache_store_unique(pseudo_class_Arraystub)) {
291 log_text("could not cache pseudo_class_Arraystub");
295 if (!link_class(pseudo_class_Arraystub))
298 /* pseudo class representing the null type */
300 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
301 pseudo_class_Null->state |= CLASS_LOADED;
302 pseudo_class_Null->super.cls = class_java_lang_Object;
304 if (!classcache_store_unique(pseudo_class_Null))
305 vm_abort("linker_init: could not cache pseudo_class_Null");
307 if (!link_class(pseudo_class_Null))
310 /* pseudo class representing new uninitialized objects */
312 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
313 pseudo_class_New->state |= CLASS_LOADED;
314 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
315 pseudo_class_New->super.cls = class_java_lang_Object;
317 if (!classcache_store_unique(pseudo_class_New))
318 vm_abort("linker_init: could not cache pseudo_class_New");
320 /* Correct vftbl-entries (retarded loading and linking of class
321 java/lang/String). */
323 stringtable_update();
329 /* link_class ******************************************************************
331 Wrapper function for link_class_intern to ease monitor enter/exit
332 and exception handling.
334 *******************************************************************************/
336 classinfo *link_class(classinfo *c)
339 #if defined(ENABLE_RT_TIMING)
340 struct timespec time_start, time_end;
343 RT_TIMING_GET_TIME(time_start);
346 exceptions_throw_nullpointerexception();
350 LOCK_MONITOR_ENTER(c);
352 /* Maybe the class is currently linking or is already linked.*/
354 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
355 LOCK_MONITOR_EXIT(c);
360 #if defined(ENABLE_STATISTICS)
363 if (opt_getcompilingtime)
364 compilingtime_stop();
366 if (opt_getloadingtime)
370 /* call the internal function */
372 r = link_class_intern(c);
374 /* If return value is NULL, we had a problem and the class is not
378 c->state &= ~CLASS_LINKING;
380 #if defined(ENABLE_STATISTICS)
383 if (opt_getloadingtime)
386 if (opt_getcompilingtime)
387 compilingtime_start();
390 LOCK_MONITOR_EXIT(c);
392 RT_TIMING_GET_TIME(time_end);
394 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
400 /* linker_overwrite_method *****************************************************
402 Overwrite a method with another one, update method flags and check
406 mg................the general method being overwritten
407 ms................the overwriting (more specialized) method
408 wl................worklist where to add invalidated methods
411 true..............everything ok
412 false.............an exception has been thrown
414 *******************************************************************************/
416 static bool linker_overwrite_method(methodinfo *mg,
418 method_worklist **wl)
426 /* overriding a final method is illegal */
428 if (mg->flags & ACC_FINAL) {
429 exceptions_throw_verifyerror(mg, "Overriding final method");
433 /* method ms overwrites method mg */
435 #if defined(ENABLE_VERIFIER)
436 /* Add loading constraints (for the more general types of method mg). */
437 /* Not for <init>, as it is not invoked virtually. */
439 if ((ms->name != utf_init)
440 && !classcache_add_constraints_for_params(
441 cs->classloader, cg->classloader, mg))
447 /* inherit the vftbl index, and record the overwriting */
449 ms->vftblindex = mg->vftblindex;
452 /* update flags and check assumptions */
453 /* <init> methods are a special case, as they are never dispatched dynamically */
455 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
457 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
458 /* this adds another implementation */
460 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
462 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
464 method_break_assumption_monomorphic(mg, wl);
467 /* this is the first implementation */
469 mg->flags |= ACC_METHOD_IMPLEMENTED;
471 INLINELOG( printf("becomes implemented: "); method_println(mg); );
476 } while (mg != NULL);
483 /* link_class_intern ***********************************************************
485 Tries to link a class. The function calculates the length in bytes
486 that an instance of this class requires as well as the VTBL for
487 methods and interface methods.
489 *******************************************************************************/
491 static classinfo *link_class_intern(classinfo *c)
493 classinfo *super; /* super class */
494 classinfo *tc; /* temporary class variable */
495 s4 supervftbllength; /* vftbllegnth of super class */
496 s4 vftbllength; /* vftbllength of current class */
497 s4 interfacetablelength; /* interface table length */
498 vftbl_t *v; /* vftbl of current class */
499 s4 i; /* interface/method/field counter */
500 arraydescriptor *arraydesc; /* descriptor for array classes */
501 method_worklist *worklist; /* worklist for recompilation */
502 #if defined(ENABLE_RT_TIMING)
503 struct timespec time_start, time_resolving, time_compute_vftbl,
504 time_abstract, time_compute_iftbl, time_fill_vftbl,
505 time_offsets, time_fill_iftbl, time_finalizer,
509 RT_TIMING_GET_TIME(time_start);
513 log_message_class("Linking class: ", c);
516 /* the class must be loaded */
518 /* XXX should this be a specific exception? */
519 assert(c->state & CLASS_LOADED);
521 /* This is check in link_class. */
523 assert(!(c->state & CLASS_LINKED));
525 /* cache the self-reference of this class */
526 /* we do this for cases where the defining loader of the class */
527 /* has not yet been recorded as an initiating loader for the class */
528 /* this is needed so subsequent code can assume that self-refs */
529 /* will always resolve lazily */
530 /* No need to do it for the bootloader - it is always registered */
531 /* as initiating loader for the classes it loads. */
533 classcache_store(c->classloader,c,false);
535 /* this class is currently linking */
537 c->state |= CLASS_LINKING;
542 /* check interfaces */
544 for (i = 0; i < c->interfacescount; i++) {
545 /* resolve this super interface */
547 if ((tc = resolve_classref_or_classinfo_eager(c->interfaces[i], true)) == NULL)
550 c->interfaces[i].cls = tc;
552 /* detect circularity */
555 exceptions_throw_classcircularityerror(c);
559 assert(tc->state & CLASS_LOADED);
561 if (!(tc->flags & ACC_INTERFACE)) {
562 exceptions_throw_incompatibleclasschangeerror(tc,
563 "Implementing class");
567 if (!(tc->state & CLASS_LINKED))
572 /* check super class */
576 if (c->super.any == NULL) { /* class java.lang.Object */
578 c->instancesize = sizeof(java_object_t);
580 vftbllength = supervftbllength = 0;
586 /* Resolve super class. */
588 super = resolve_classref_or_classinfo_eager(c->super, true);
593 c->super.cls = super;
595 /* Detect circularity. */
598 exceptions_throw_classcircularityerror(c);
602 assert(super->state & CLASS_LOADED);
604 if (super->flags & ACC_INTERFACE) {
605 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
606 log_text("Interface specified as super class");
610 /* Don't allow extending final classes */
612 if (super->flags & ACC_FINAL) {
613 exceptions_throw_verifyerror(NULL,
614 "Cannot inherit from final class");
618 /* link the superclass if necessary */
620 if (!(super->state & CLASS_LINKED))
621 if (!link_class(super))
624 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
627 c->flags |= (super->flags &
628 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
630 /* handle array classes */
632 if (c->name->text[0] == '[')
633 if (!(arraydesc = link_array(c)))
636 if (c->flags & ACC_INTERFACE)
637 c->index = interfaceindex++;
639 c->index = super->index + 1;
641 c->instancesize = super->instancesize;
643 vftbllength = supervftbllength = super->vftbl->vftbllength;
645 c->finalizer = super->finalizer;
647 RT_TIMING_GET_TIME(time_resolving);
650 /* compute vftbl length */
652 for (i = 0; i < c->methodscount; i++) {
653 methodinfo *m = &(c->methods[i]);
655 if (!(m->flags & ACC_STATIC)) { /* is instance method */
661 for (j = 0; j < tc->methodscount; j++) {
662 if (method_canoverwrite(m, &(tc->methods[j]))) {
663 if (tc->methods[j].flags & ACC_PRIVATE)
664 goto notfoundvftblindex;
666 /* package-private methods in other packages */
667 /* must not be overridden */
668 /* (see Java Language Specification 8.4.8.1) */
669 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
670 && !SAME_PACKAGE(c,tc) )
672 goto notfoundvftblindex;
675 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
678 goto foundvftblindex;
686 m->vftblindex = (vftbllength++);
691 RT_TIMING_GET_TIME(time_compute_vftbl);
694 /* Check all interfaces of an abstract class (maybe be an
695 interface too) for unimplemented methods. Such methods are
696 called miranda-methods and are marked with the ACC_MIRANDA
697 flag. VMClass.getDeclaredMethods does not return such
700 if (c->flags & ACC_ABSTRACT) {
703 s4 abstractmethodscount;
707 abstractmethodscount = 0;
709 /* check all interfaces of the abstract class */
711 for (i = 0; i < c->interfacescount; i++) {
712 ic = c->interfaces[i].cls;
714 for (j = 0; j < ic->methodscount; j++) {
715 im = &(ic->methods[j]);
717 /* skip `<clinit>' and `<init>' */
719 if ((im->name == utf_clinit) || (im->name == utf_init))
722 for (tc = c; tc != NULL; tc = tc->super.cls) {
723 for (k = 0; k < tc->methodscount; k++) {
724 if (method_canoverwrite(im, &(tc->methods[k])))
725 goto noabstractmethod;
729 abstractmethodscount++;
736 if (abstractmethodscount > 0) {
739 /* reallocate methods memory */
741 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
742 c->methodscount + abstractmethodscount);
744 for (i = 0; i < c->interfacescount; i++) {
745 ic = c->interfaces[i].cls;
747 for (j = 0; j < ic->methodscount; j++) {
748 im = &(ic->methods[j]);
750 /* skip `<clinit>' and `<init>' */
752 if ((im->name == utf_clinit) || (im->name == utf_init))
755 for (tc = c; tc != NULL; tc = tc->super.cls) {
756 for (k = 0; k < tc->methodscount; k++) {
757 if (method_canoverwrite(im, &(tc->methods[k])))
758 goto noabstractmethod2;
762 /* Copy the method found into the new c->methods
763 array and tag it as miranda-method. */
765 am = &(c->methods[c->methodscount]);
768 MCOPY(am, im, methodinfo, 1);
770 am->vftblindex = (vftbllength++);
772 am->flags |= ACC_MIRANDA;
780 RT_TIMING_GET_TIME(time_abstract);
783 #if defined(ENABLE_STATISTICS)
786 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
789 /* compute interfacetable length */
791 interfacetablelength = 0;
793 for (tc = c; tc != NULL; tc = tc->super.cls) {
794 for (i = 0; i < tc->interfacescount; i++) {
795 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
797 if (h > interfacetablelength)
798 interfacetablelength = h;
801 RT_TIMING_GET_TIME(time_compute_iftbl);
803 /* allocate virtual function table */
805 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
806 sizeof(methodptr) * (vftbllength - 1) +
807 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
808 v = (vftbl_t *) (((methodptr *) v) +
809 (interfacetablelength - 1) * (interfacetablelength > 1));
813 v->vftbllength = vftbllength;
814 v->interfacetablelength = interfacetablelength;
815 v->arraydesc = arraydesc;
817 /* store interface index in vftbl */
819 if (c->flags & ACC_INTERFACE)
820 v->baseval = -(c->index);
822 /* copy virtual function table of super class */
824 for (i = 0; i < supervftbllength; i++)
825 v->table[i] = super->vftbl->table[i];
827 /* Fill the remaining vftbl slots with the AbstractMethodError
828 stub (all after the super class slots, because they are already
831 for (; i < vftbllength; i++) {
832 #if defined(ENABLE_JIT)
833 # if defined(ENABLE_INTRP)
835 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
838 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
840 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
844 /* add method stubs into virtual function table */
846 for (i = 0; i < c->methodscount; i++) {
847 methodinfo *m = &(c->methods[i]);
849 assert(m->stubroutine == NULL);
851 /* Don't create a compiler stub for abstract methods as they
852 throw an AbstractMethodError with the default stub in the
853 vftbl. This entry is simply copied by sub-classes. */
855 if (m->flags & ACC_ABSTRACT)
858 #if defined(ENABLE_JIT)
859 # if defined(ENABLE_INTRP)
861 m->stubroutine = intrp_createcompilerstub(m);
864 m->stubroutine = codegen_generate_stub_compiler(m);
866 m->stubroutine = intrp_createcompilerstub(m);
869 /* static methods are not in the vftbl */
871 if (m->flags & ACC_STATIC)
874 /* insert the stubroutine into the vftbl */
876 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
878 RT_TIMING_GET_TIME(time_fill_vftbl);
880 /* compute instance size and offset of each field */
882 for (i = 0; i < c->fieldscount; i++) {
884 fieldinfo *f = &(c->fields[i]);
886 if (!(f->flags & ACC_STATIC)) {
887 dsize = descriptor_typesize(f->parseddesc);
889 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__))
890 /* On i386 and ARM we align double and s8 fields to
891 4-bytes. This matches what GCC does for struct
892 members. We must do the same as gcc here because the
893 offsets in native header structs like java_lang_Double
894 must match the offsets of the Java fields
895 (eg. java.lang.Double.value). */
897 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
899 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
902 f->offset = c->instancesize;
903 c->instancesize += dsize;
906 RT_TIMING_GET_TIME(time_offsets);
908 /* initialize interfacetable and interfacevftbllength */
910 v->interfacevftbllength = MNEW(s4, interfacetablelength);
912 #if defined(ENABLE_STATISTICS)
914 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
917 for (i = 0; i < interfacetablelength; i++) {
918 v->interfacevftbllength[i] = 0;
919 v->interfacetable[-i] = NULL;
924 for (tc = c; tc != NULL; tc = tc->super.cls)
925 for (i = 0; i < tc->interfacescount; i++)
926 if (!linker_addinterface(c, tc->interfaces[i].cls))
929 RT_TIMING_GET_TIME(time_fill_iftbl);
931 /* add finalizer method (not for java.lang.Object) */
936 fi = class_findmethod(c, utf_finalize, utf_void__void);
939 if (!(fi->flags & ACC_STATIC))
942 RT_TIMING_GET_TIME(time_finalizer);
946 linker_compute_subclasses(c);
948 RT_TIMING_GET_TIME(time_subclasses);
950 /* revert the linking state and class is linked */
952 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
956 /* XXX must this also be done in case of exception? */
958 while (worklist != NULL) {
959 method_worklist *wi = worklist;
961 worklist = worklist->next;
963 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
964 jit_invalidate_code(wi->m);
966 /* XXX put worklist into dump memory? */
967 FREE(wi, method_worklist);
972 log_message_class("Linking done class: ", c);
975 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
976 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
977 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
978 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
979 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
980 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
981 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
982 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
983 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
985 /* just return c to show that we didn't had a problem */
991 /* link_array ******************************************************************
993 This function is called by link_class to create the arraydescriptor
996 This function returns NULL if the array cannot be linked because
997 the component type has not been linked yet.
999 *******************************************************************************/
1001 static arraydescriptor *link_array(classinfo *c)
1005 arraydescriptor *desc;
1010 namelen = c->name->blength;
1012 /* Check the component type */
1014 switch (c->name->text[1]) {
1016 /* c is an array of arrays. */
1017 u = utf_new(c->name->text + 1, namelen - 1);
1018 if (!(comp = load_class_from_classloader(u, c->classloader)))
1023 /* c is an array of objects. */
1024 u = utf_new(c->name->text + 2, namelen - 3);
1025 if (!(comp = load_class_from_classloader(u, c->classloader)))
1030 /* If the component type has not been linked, link it now */
1032 assert(!comp || (comp->state & CLASS_LOADED));
1034 if (comp && !(comp->state & CLASS_LINKED))
1035 if (!link_class(comp))
1038 /* Allocate the arraydescriptor */
1040 desc = NEW(arraydescriptor);
1043 /* c is an array of references */
1044 desc->arraytype = ARRAYTYPE_OBJECT;
1045 desc->componentsize = sizeof(void*);
1046 desc->dataoffset = OFFSET(java_objectarray_t, data);
1048 compvftbl = comp->vftbl;
1051 log_text("Component class has no vftbl");
1055 desc->componentvftbl = compvftbl;
1057 if (compvftbl->arraydesc) {
1058 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1060 if (compvftbl->arraydesc->dimension >= 255) {
1061 log_text("Creating array of dimension >255");
1065 desc->dimension = compvftbl->arraydesc->dimension + 1;
1066 desc->elementtype = compvftbl->arraydesc->elementtype;
1069 desc->elementvftbl = compvftbl;
1070 desc->dimension = 1;
1071 desc->elementtype = ARRAYTYPE_OBJECT;
1075 /* c is an array of a primitive type */
1076 switch (c->name->text[1]) {
1078 desc->arraytype = ARRAYTYPE_BOOLEAN;
1079 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1080 desc->componentsize = sizeof(u1);
1084 desc->arraytype = ARRAYTYPE_BYTE;
1085 desc->dataoffset = OFFSET(java_bytearray_t,data);
1086 desc->componentsize = sizeof(u1);
1090 desc->arraytype = ARRAYTYPE_CHAR;
1091 desc->dataoffset = OFFSET(java_chararray_t,data);
1092 desc->componentsize = sizeof(u2);
1096 desc->arraytype = ARRAYTYPE_DOUBLE;
1097 desc->dataoffset = OFFSET(java_doublearray_t,data);
1098 desc->componentsize = sizeof(double);
1102 desc->arraytype = ARRAYTYPE_FLOAT;
1103 desc->dataoffset = OFFSET(java_floatarray_t,data);
1104 desc->componentsize = sizeof(float);
1108 desc->arraytype = ARRAYTYPE_INT;
1109 desc->dataoffset = OFFSET(java_intarray_t,data);
1110 desc->componentsize = sizeof(s4);
1114 desc->arraytype = ARRAYTYPE_LONG;
1115 desc->dataoffset = OFFSET(java_longarray_t,data);
1116 desc->componentsize = sizeof(s8);
1120 desc->arraytype = ARRAYTYPE_SHORT;
1121 desc->dataoffset = OFFSET(java_shortarray_t,data);
1122 desc->componentsize = sizeof(s2);
1126 exceptions_throw_noclassdeffounderror(c->name);
1130 desc->componentvftbl = NULL;
1131 desc->elementvftbl = NULL;
1132 desc->dimension = 1;
1133 desc->elementtype = desc->arraytype;
1140 /* linker_compute_subclasses ***************************************************
1144 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1145 This function needs to take the class renumber lock and stop the
1146 world during class renumbering. The lock is used in C code which
1147 is not that performance critical. Whereas JIT code uses critical
1148 sections to atomically access the class values.
1150 *******************************************************************************/
1152 static void linker_compute_subclasses(classinfo *c)
1154 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1156 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1157 threads_cast_stopworld();
1160 if (!(c->flags & ACC_INTERFACE)) {
1165 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1166 c->nextsub = c->super.cls->sub;
1167 c->super.cls->sub = c;
1172 /* compute class values */
1174 linker_compute_class_values(class_java_lang_Object);
1176 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1178 #if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
1179 threads_cast_startworld();
1184 /* linker_compute_class_values *************************************************
1188 *******************************************************************************/
1190 static void linker_compute_class_values(classinfo *c)
1194 c->vftbl->baseval = ++classvalue;
1199 linker_compute_class_values(subs);
1201 subs = subs->nextsub;
1204 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1208 /* linker_addinterface *********************************************************
1210 Is needed by link_class for adding a VTBL to a class. All
1211 interfaces implemented by ic are added as well.
1214 true.........everything ok
1215 false........an exception has been thrown
1217 *******************************************************************************/
1219 static bool linker_addinterface(classinfo *c, classinfo *ic)
1230 if (i >= v->interfacetablelength)
1231 vm_abort("Internal error: interfacetable overflow");
1233 /* if this interface has already been added, return immediately */
1235 if (v->interfacetable[-i] != NULL)
1238 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1239 v->interfacevftbllength[i] = 1;
1240 v->interfacetable[-i] = MNEW(methodptr, 1);
1241 v->interfacetable[-i][0] = NULL;
1244 v->interfacevftbllength[i] = ic->methodscount;
1245 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1247 #if defined(ENABLE_STATISTICS)
1249 count_vftbl_len += sizeof(methodptr) *
1250 (ic->methodscount + (ic->methodscount == 0));
1253 for (j = 0; j < ic->methodscount; j++) {
1254 for (sc = c; sc != NULL; sc = sc->super.cls) {
1255 for (k = 0; k < sc->methodscount; k++) {
1256 m = &(sc->methods[k]);
1258 if (method_canoverwrite(m, &(ic->methods[j]))) {
1259 /* method m overwrites the (abstract) method */
1260 #if defined(ENABLE_VERIFIER)
1261 /* Add loading constraints (for the more
1262 general types of the method
1264 if (!classcache_add_constraints_for_params(
1265 c->classloader, ic->classloader,
1272 /* XXX taken from gcj */
1273 /* check for ACC_STATIC: IncompatibleClassChangeError */
1275 /* check for !ACC_PUBLIC: IllegalAccessError */
1277 /* check for ACC_ABSTRACT: AbstracMethodError,
1278 not sure about that one */
1280 v->interfacetable[-i][j] = v->table[m->vftblindex];
1286 /* If no method was found, insert the AbstractMethodError
1289 #if defined(ENABLE_JIT)
1290 # if defined(ENABLE_INTRP)
1292 v->interfacetable[-i][j] =
1293 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1296 v->interfacetable[-i][j] =
1297 (methodptr) (ptrint) &asm_abstractmethoderror;
1299 v->interfacetable[-i][j] =
1300 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1308 /* add superinterfaces of this interface */
1310 for (j = 0; j < ic->interfacescount; j++)
1311 if (!linker_addinterface(c, ic->interfaces[j].cls))
1320 /* class_highestinterface ******************************************************
1322 Used by the function link_class to determine the amount of memory
1323 needed for the interface table.
1325 *******************************************************************************/
1327 static s4 class_highestinterface(classinfo *c)
1333 /* check for ACC_INTERFACE bit already done in link_class_intern */
1337 for (i = 0; i < c->interfacescount; i++) {
1338 h2 = class_highestinterface(c->interfaces[i].cls);
1349 * These are local overrides for various environment variables in Emacs.
1350 * Please do not remove this and leave it at the end of the file, where
1351 * Emacs will automagically detect them.
1352 * ---------------------------------------------------------------------
1355 * indent-tabs-mode: t
1359 * vim:noexpandtab:sw=4:ts=4: