1 /* src/vmcore/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "native/native.h"
37 #include "threads/lock-common.h"
39 #include "toolbox/logging.h"
41 #include "vm/access.h"
43 #include "vm/exceptions.h"
44 #include "vm/primitive.hpp"
45 #include "vm/stringlocal.h"
48 #include "vm/jit_interface.h"
50 #include "vmcore/class.h"
51 #include "vmcore/classcache.h"
52 #include "vmcore/loader.h"
53 #include "vmcore/options.h"
54 #include "vmcore/rt-timing.h"
57 /* debugging macros ***********************************************************/
60 # define TRACELINKCLASS(c) \
62 if (opt_TraceLinkClass) { \
64 log_print("[Linking "); \
71 # define TRACELINKCLASS(c)
75 /* #include "vm/resolve.h" */
76 /* copied prototype to avoid bootstrapping problem: */
77 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
79 #if defined(ENABLE_STATISTICS)
80 # include "vmcore/statistics.h"
83 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
84 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
86 #define INLINELOG(code)
90 /* global variables ***********************************************************/
92 static s4 interfaceindex; /* sequential numbering of interfaces */
95 java_object_t *linker_classrenumber_lock;
98 /* private functions **********************************************************/
100 static classinfo *link_class_intern(classinfo *c);
101 static arraydescriptor *link_array(classinfo *c);
102 static void linker_compute_class_values(classinfo *c);
103 static void linker_compute_subclasses(classinfo *c);
104 static bool linker_addinterface(classinfo *c, classinfo *ic);
105 static s4 class_highestinterface(classinfo *c);
108 /* dummy structures for alinment checks ***************************************/
110 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
111 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
113 struct dummy_alignment_long_t {
118 struct dummy_alignment_double_t {
124 /* linker_init *****************************************************************
126 Initializes the linker subsystem and links classes required for the
129 *******************************************************************************/
131 void linker_preinit(void)
133 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
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 /* Define a define here which is later checked when we use this
142 # define LINKER_ALIGNMENT_LONG_DOUBLE 4
144 if (OFFSET(dummy_alignment_long_t, l) != 4)
145 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
146 OFFSET(dummy_alignment_long_t, l), 4);
148 if (OFFSET(dummy_alignment_double_t, d) != 4)
149 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
150 OFFSET(dummy_alignment_double_t, d), 4);
153 # define LINKER_ALIGNMENT_LONG_DOUBLE 8
155 if (OFFSET(dummy_alignment_long_t, l) != 8)
156 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
157 OFFSET(dummy_alignment_long_t, l), 8);
159 if (OFFSET(dummy_alignment_double_t, d) != 8)
160 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
161 OFFSET(dummy_alignment_double_t, d), 8);
164 /* Reset interface index. */
168 #if defined(ENABLE_THREADS)
169 /* create the global lock object */
171 linker_classrenumber_lock = NEW(java_object_t);
173 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
176 /* Link the most basic classes. */
178 if (!link_class(class_java_lang_Object))
179 vm_abort("linker_preinit: linking java/lang/Object failed");
181 #if defined(ENABLE_JAVASE)
182 if (!link_class(class_java_lang_Cloneable))
183 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
185 if (!link_class(class_java_io_Serializable))
186 vm_abort("linker_preinit: linking java/io/Serializable failed");
191 /* linker_init *****************************************************************
193 Links all classes required in the VM.
195 *******************************************************************************/
197 void linker_init(void)
199 TRACESUBSYSTEMINITIALIZATION("linker_init");
201 /* Link java.lang.Class as first class of the system, because we
202 need it's vftbl for all other classes so we can use a class as
205 if (!link_class(class_java_lang_Class))
206 vm_abort("linker_init: linking java/lang/Class failed");
208 /* Now set the header.vftbl of all classes which were created
209 before java.lang.Class was linked. */
211 class_postset_header_vftbl();
213 /* Link primitive-type wrapping classes. */
215 #if defined(ENABLE_JAVASE)
216 if (!link_class(class_java_lang_Void))
217 vm_abort("linker_init: linking failed");
220 if (!link_class(class_java_lang_Boolean))
221 vm_abort("linker_init: linking failed");
223 if (!link_class(class_java_lang_Byte))
224 vm_abort("linker_init: linking failed");
226 if (!link_class(class_java_lang_Character))
227 vm_abort("linker_init: linking failed");
229 if (!link_class(class_java_lang_Short))
230 vm_abort("linker_init: linking failed");
232 if (!link_class(class_java_lang_Integer))
233 vm_abort("linker_init: linking failed");
235 if (!link_class(class_java_lang_Long))
236 vm_abort("linker_init: linking failed");
238 if (!link_class(class_java_lang_Float))
239 vm_abort("linker_init: linking failed");
241 if (!link_class(class_java_lang_Double))
242 vm_abort("linker_init: linking failed");
244 /* Link important system classes. */
246 if (!link_class(class_java_lang_String))
247 vm_abort("linker_init: linking java/lang/String failed");
249 #if defined(ENABLE_JAVASE)
250 if (!link_class(class_java_lang_ClassLoader))
251 vm_abort("linker_init: linking failed");
253 if (!link_class(class_java_lang_SecurityManager))
254 vm_abort("linker_init: linking failed");
257 if (!link_class(class_java_lang_System))
258 vm_abort("linker_init: linking failed");
260 if (!link_class(class_java_lang_Thread))
261 vm_abort("linker_init: linking failed");
263 #if defined(ENABLE_JAVASE)
264 if (!link_class(class_java_lang_ThreadGroup))
265 vm_abort("linker_init: linking failed");
268 if (!link_class(class_java_lang_Throwable))
269 vm_abort("linker_init: linking failed");
271 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
272 if (!link_class(class_java_lang_VMSystem))
273 vm_abort("linker_init: linking failed");
275 if (!link_class(class_java_lang_VMThread))
276 vm_abort("linker_init: linking failed");
278 if (!link_class(class_java_lang_VMThrowable))
279 vm_abort("linker_init: linking failed");
282 /* Important system exceptions. */
284 if (!link_class(class_java_lang_Exception))
285 vm_abort("linker_init: linking failed");
287 if (!link_class(class_java_lang_ClassNotFoundException))
288 vm_abort("linker_init: linking failed");
290 if (!link_class(class_java_lang_RuntimeException))
291 vm_abort("linker_init: linking failed");
293 /* some classes which may be used more often */
295 #if defined(ENABLE_JAVASE)
296 if (!link_class(class_java_lang_StackTraceElement))
297 vm_abort("linker_init: linking failed");
299 if (!link_class(class_java_lang_reflect_Constructor))
300 vm_abort("linker_init: linking failed");
302 if (!link_class(class_java_lang_reflect_Field))
303 vm_abort("linker_init: linking failed");
305 if (!link_class(class_java_lang_reflect_Method))
306 vm_abort("linker_init: linking failed");
308 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
309 if (!link_class(class_java_lang_reflect_VMConstructor))
310 vm_abort("linker_init: linking failed");
312 if (!link_class(class_java_lang_reflect_VMField))
313 vm_abort("linker_init: linking failed");
315 if (!link_class(class_java_lang_reflect_VMMethod))
316 vm_abort("linker_init: linking failed");
319 if (!link_class(class_java_security_PrivilegedAction))
320 vm_abort("linker_init: linking failed");
322 if (!link_class(class_java_util_Vector))
323 vm_abort("linker_init: linking failed");
325 if (!link_class(class_java_util_HashMap))
326 vm_abort("linker_init: linking failed");
328 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
329 if (!link_class(class_sun_reflect_MagicAccessorImpl))
330 vm_abort("linker_init: linking failed");
333 if (!link_class(arrayclass_java_lang_Object))
334 vm_abort("linker_init: linking failed");
338 /* create pseudo classes used by the typechecker */
340 /* pseudo class for Arraystubs (extends java.lang.Object) */
342 pseudo_class_Arraystub =
343 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
344 pseudo_class_Arraystub->state |= CLASS_LOADED;
345 pseudo_class_Arraystub->super = class_java_lang_Object;
347 #if defined(ENABLE_JAVASE)
349 pseudo_class_Arraystub->interfacescount = 2;
350 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
351 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
352 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
354 #elif defined(ENABLE_JAVAME_CLDC1_1)
356 pseudo_class_Arraystub->interfacescount = 0;
357 pseudo_class_Arraystub->interfaces = NULL;
360 # error unknown Java configuration
363 if (!classcache_store_unique(pseudo_class_Arraystub))
364 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
366 if (!link_class(pseudo_class_Arraystub))
367 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
369 /* pseudo class representing the null type */
371 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
372 pseudo_class_Null->state |= CLASS_LOADED;
373 pseudo_class_Null->super = class_java_lang_Object;
375 if (!classcache_store_unique(pseudo_class_Null))
376 vm_abort("linker_init: could not cache pseudo_class_Null");
378 if (!link_class(pseudo_class_Null))
379 vm_abort("linker_init: linking failed");
381 /* pseudo class representing new uninitialized objects */
383 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
384 pseudo_class_New->state |= CLASS_LOADED;
385 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
386 pseudo_class_New->super = class_java_lang_Object;
388 if (!classcache_store_unique(pseudo_class_New))
389 vm_abort("linker_init: could not cache pseudo_class_New");
391 /* Correct vftbl-entries (retarded loading and linking of class
392 java/lang/String). */
394 stringtable_update();
398 /* link_class ******************************************************************
400 Wrapper function for link_class_intern to ease monitor enter/exit
401 and exception handling.
403 *******************************************************************************/
405 classinfo *link_class(classinfo *c)
408 #if defined(ENABLE_RT_TIMING)
409 struct timespec time_start, time_end;
412 RT_TIMING_GET_TIME(time_start);
415 exceptions_throw_nullpointerexception();
419 LOCK_MONITOR_ENTER(c);
421 /* Maybe the class is currently linking or is already linked.*/
423 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
424 LOCK_MONITOR_EXIT(c);
429 #if defined(ENABLE_STATISTICS)
432 if (opt_getcompilingtime)
433 compilingtime_stop();
435 if (opt_getloadingtime)
439 /* call the internal function */
441 r = link_class_intern(c);
443 /* If return value is NULL, we had a problem and the class is not
447 c->state &= ~CLASS_LINKING;
449 #if defined(ENABLE_STATISTICS)
452 if (opt_getloadingtime)
455 if (opt_getcompilingtime)
456 compilingtime_start();
459 LOCK_MONITOR_EXIT(c);
461 RT_TIMING_GET_TIME(time_end);
463 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
469 /* linker_overwrite_method *****************************************************
471 Overwrite a method with another one, update method flags and check
475 mg................the general method being overwritten
476 ms................the overwriting (more specialized) method
477 wl................worklist where to add invalidated methods
480 true..............everything ok
481 false.............an exception has been thrown
483 *******************************************************************************/
485 static bool linker_overwrite_method(methodinfo *mg,
487 method_worklist **wl)
495 /* overriding a final method is illegal */
497 if (mg->flags & ACC_FINAL) {
498 exceptions_throw_verifyerror(mg, "Overriding final method");
502 /* method ms overwrites method mg */
504 #if defined(ENABLE_VERIFIER)
505 /* Add loading constraints (for the more general types of method mg). */
506 /* Not for <init>, as it is not invoked virtually. */
508 if ((ms->name != utf_init)
509 && !classcache_add_constraints_for_params(
510 cs->classloader, cg->classloader, mg))
516 /* inherit the vftbl index, and record the overwriting */
518 ms->vftblindex = mg->vftblindex;
521 /* update flags and check assumptions */
522 /* <init> methods are a special case, as they are never dispatched dynamically */
524 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
527 #if defined(ENABLE_TLH)
528 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
529 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
530 ms->clazz->name->text, ms->name->text);
531 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
535 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
536 /* this adds another implementation */
538 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
540 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
542 method_break_assumption_monomorphic(mg, wl);
545 /* this is the first implementation */
547 mg->flags |= ACC_METHOD_IMPLEMENTED;
549 INLINELOG( printf("becomes implemented: "); method_println(mg); );
554 } while (mg != NULL);
561 /* link_class_intern ***********************************************************
563 Tries to link a class. The function calculates the length in bytes
564 that an instance of this class requires as well as the VTBL for
565 methods and interface methods.
567 *******************************************************************************/
569 static classinfo *link_class_intern(classinfo *c)
571 classinfo *super; /* super class */
572 classinfo *tc; /* temporary class variable */
573 s4 supervftbllength; /* vftbllegnth of super class */
574 s4 vftbllength; /* vftbllength of current class */
575 s4 interfacetablelength; /* interface table length */
576 vftbl_t *v; /* vftbl of current class */
577 s4 i; /* interface/method/field counter */
578 arraydescriptor *arraydesc; /* descriptor for array classes */
579 method_worklist *worklist; /* worklist for recompilation */
580 #if defined(ENABLE_RT_TIMING)
581 struct timespec time_start, time_resolving, time_compute_vftbl,
582 time_abstract, time_compute_iftbl, time_fill_vftbl,
583 time_offsets, time_fill_iftbl, time_finalizer,
587 RT_TIMING_GET_TIME(time_start);
591 /* the class must be loaded */
593 /* XXX should this be a specific exception? */
594 assert(c->state & CLASS_LOADED);
596 /* This is check in link_class. */
598 assert(!(c->state & CLASS_LINKED));
600 /* cache the self-reference of this class */
601 /* we do this for cases where the defining loader of the class */
602 /* has not yet been recorded as an initiating loader for the class */
603 /* this is needed so subsequent code can assume that self-refs */
604 /* will always resolve lazily */
605 /* No need to do it for the bootloader - it is always registered */
606 /* as initiating loader for the classes it loads. */
608 classcache_store(c->classloader,c,false);
610 /* this class is currently linking */
612 c->state |= CLASS_LINKING;
617 /* Link the super interfaces. */
619 for (i = 0; i < c->interfacescount; i++) {
620 tc = c->interfaces[i];
622 if (!(tc->state & CLASS_LINKED))
627 /* check super class */
631 /* Check for java/lang/Object. */
633 if (c->super == NULL) {
635 c->instancesize = sizeof(java_object_t);
637 vftbllength = supervftbllength = 0;
642 /* Get super class. */
646 /* Link the super class if necessary. */
648 if (!(super->state & CLASS_LINKED))
649 if (!link_class(super))
652 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
655 c->flags |= (super->flags &
656 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
658 /* handle array classes */
660 if (c->name->text[0] == '[')
661 if (!(arraydesc = link_array(c)))
664 if (c->flags & ACC_INTERFACE)
665 c->index = interfaceindex++;
667 c->index = super->index + 1;
669 c->instancesize = super->instancesize;
671 vftbllength = supervftbllength = super->vftbl->vftbllength;
673 c->finalizer = super->finalizer;
675 RT_TIMING_GET_TIME(time_resolving);
678 /* compute vftbl length */
680 for (i = 0; i < c->methodscount; i++) {
681 methodinfo *m = &(c->methods[i]);
683 if (!(m->flags & ACC_STATIC)) { /* is instance method */
689 for (j = 0; j < tc->methodscount; j++) {
690 if (method_canoverwrite(m, &(tc->methods[j]))) {
691 if (tc->methods[j].flags & ACC_PRIVATE)
692 goto notfoundvftblindex;
694 /* package-private methods in other packages */
695 /* must not be overridden */
696 /* (see Java Language Specification 8.4.8.1) */
697 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
698 && !SAME_PACKAGE(c,tc) )
700 goto notfoundvftblindex;
703 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
706 goto foundvftblindex;
714 m->vftblindex = (vftbllength++);
719 RT_TIMING_GET_TIME(time_compute_vftbl);
722 /* Check all interfaces of an abstract class (maybe be an
723 interface too) for unimplemented methods. Such methods are
724 called miranda-methods and are marked with the ACC_MIRANDA
725 flag. VMClass.getDeclaredMethods does not return such
728 if (c->flags & ACC_ABSTRACT) {
731 s4 abstractmethodscount;
735 abstractmethodscount = 0;
737 /* check all interfaces of the abstract class */
739 for (i = 0; i < c->interfacescount; i++) {
740 ic = c->interfaces[i];
742 for (j = 0; j < ic->methodscount; j++) {
743 im = &(ic->methods[j]);
745 /* skip `<clinit>' and `<init>' */
747 if ((im->name == utf_clinit) || (im->name == utf_init))
750 for (tc = c; tc != NULL; tc = tc->super) {
751 for (k = 0; k < tc->methodscount; k++) {
752 if (method_canoverwrite(im, &(tc->methods[k])))
753 goto noabstractmethod;
757 abstractmethodscount++;
764 if (abstractmethodscount > 0) {
767 /* reallocate methods memory */
769 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
770 c->methodscount + abstractmethodscount);
772 for (i = 0; i < c->interfacescount; i++) {
773 ic = c->interfaces[i];
775 for (j = 0; j < ic->methodscount; j++) {
776 im = &(ic->methods[j]);
778 /* skip `<clinit>' and `<init>' */
780 if ((im->name == utf_clinit) || (im->name == utf_init))
783 for (tc = c; tc != NULL; tc = tc->super) {
784 for (k = 0; k < tc->methodscount; k++) {
785 if (method_canoverwrite(im, &(tc->methods[k])))
786 goto noabstractmethod2;
790 /* Copy the method found into the new c->methods
791 array and tag it as miranda-method. */
793 am = &(c->methods[c->methodscount]);
796 MCOPY(am, im, methodinfo, 1);
798 am->vftblindex = (vftbllength++);
800 am->flags |= ACC_MIRANDA;
808 RT_TIMING_GET_TIME(time_abstract);
811 #if defined(ENABLE_STATISTICS)
814 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
817 /* compute interfacetable length */
819 interfacetablelength = 0;
821 for (tc = c; tc != NULL; tc = tc->super) {
822 for (i = 0; i < tc->interfacescount; i++) {
823 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
825 if (h > interfacetablelength)
826 interfacetablelength = h;
829 RT_TIMING_GET_TIME(time_compute_iftbl);
831 /* allocate virtual function table */
833 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
834 sizeof(methodptr) * (vftbllength - 1) +
835 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
836 v = (vftbl_t *) (((methodptr *) v) +
837 (interfacetablelength - 1) * (interfacetablelength > 1));
841 v->vftbllength = vftbllength;
842 v->interfacetablelength = interfacetablelength;
843 v->arraydesc = arraydesc;
845 /* store interface index in vftbl */
847 if (c->flags & ACC_INTERFACE)
848 v->baseval = -(c->index);
850 /* copy virtual function table of super class */
852 for (i = 0; i < supervftbllength; i++)
853 v->table[i] = super->vftbl->table[i];
855 /* Fill the remaining vftbl slots with the AbstractMethodError
856 stub (all after the super class slots, because they are already
859 for (; i < vftbllength; i++) {
860 #if defined(ENABLE_JIT)
861 # if defined(ENABLE_INTRP)
863 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
866 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
868 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
872 /* add method stubs into virtual function table */
874 for (i = 0; i < c->methodscount; i++) {
875 methodinfo *m = &(c->methods[i]);
877 assert(m->stubroutine == NULL);
879 /* Don't create a compiler stub for abstract methods as they
880 throw an AbstractMethodError with the default stub in the
881 vftbl. This entry is simply copied by sub-classes. */
883 if (m->flags & ACC_ABSTRACT)
886 #if defined(ENABLE_JIT)
887 # if defined(ENABLE_INTRP)
889 m->stubroutine = intrp_createcompilerstub(m);
892 m->stubroutine = codegen_generate_stub_compiler(m);
894 m->stubroutine = intrp_createcompilerstub(m);
897 /* static methods are not in the vftbl */
899 if (m->flags & ACC_STATIC)
902 /* insert the stubroutine into the vftbl */
904 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
906 RT_TIMING_GET_TIME(time_fill_vftbl);
908 /* compute instance size and offset of each field */
910 for (i = 0; i < c->fieldscount; i++) {
912 fieldinfo *f = &(c->fields[i]);
914 if (!(f->flags & ACC_STATIC)) {
915 dsize = descriptor_typesize(f->parseddesc);
917 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
918 /* On some architectures and configurations we need to
919 align long (int64_t) and double fields to 4-bytes to
920 match what GCC does for struct members. We must do the
921 same as GCC here because the offsets in native header
922 structs like java_lang_Double must match the offsets of
923 the Java fields (eg. java.lang.Double.value). */
925 # if LINKER_ALIGNMENT_LONG_DOUBLE != 4
926 # error alignment of long and double is not 4
929 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
932 # if LINKER_ALIGNMENT_LONG_DOUBLE != 8
933 # error alignment of long and double is not 8
936 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
939 f->offset = c->instancesize;
940 c->instancesize += dsize;
943 RT_TIMING_GET_TIME(time_offsets);
945 /* initialize interfacetable and interfacevftbllength */
947 v->interfacevftbllength = MNEW(s4, interfacetablelength);
949 #if defined(ENABLE_STATISTICS)
951 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
954 for (i = 0; i < interfacetablelength; i++) {
955 v->interfacevftbllength[i] = 0;
956 v->interfacetable[-i] = NULL;
961 for (tc = c; tc != NULL; tc = tc->super)
962 for (i = 0; i < tc->interfacescount; i++)
963 if (!linker_addinterface(c, tc->interfaces[i]))
966 RT_TIMING_GET_TIME(time_fill_iftbl);
968 /* add finalizer method (not for java.lang.Object) */
973 fi = class_findmethod(c, utf_finalize, utf_void__void);
976 if (!(fi->flags & ACC_STATIC))
979 RT_TIMING_GET_TIME(time_finalizer);
983 linker_compute_subclasses(c);
985 RT_TIMING_GET_TIME(time_subclasses);
987 /* revert the linking state and class is linked */
989 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
993 /* XXX must this also be done in case of exception? */
995 while (worklist != NULL) {
996 method_worklist *wi = worklist;
998 worklist = worklist->next;
1000 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
1001 jit_invalidate_code(wi->m);
1003 /* XXX put worklist into dump memory? */
1004 FREE(wi, method_worklist);
1007 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1008 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1009 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1010 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1011 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1012 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1013 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1014 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1015 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1017 /* just return c to show that we didn't had a problem */
1023 /* link_array ******************************************************************
1025 This function is called by link_class to create the arraydescriptor
1028 This function returns NULL if the array cannot be linked because
1029 the component type has not been linked yet.
1031 *******************************************************************************/
1033 static arraydescriptor *link_array(classinfo *c)
1037 arraydescriptor *desc;
1042 namelen = c->name->blength;
1044 /* Check the component type */
1046 switch (c->name->text[1]) {
1048 /* c is an array of arrays. */
1049 u = utf_new(c->name->text + 1, namelen - 1);
1050 if (!(comp = load_class_from_classloader(u, c->classloader)))
1055 /* c is an array of objects. */
1056 u = utf_new(c->name->text + 2, namelen - 3);
1057 if (!(comp = load_class_from_classloader(u, c->classloader)))
1062 /* If the component type has not been linked, link it now */
1064 assert(!comp || (comp->state & CLASS_LOADED));
1066 if (comp && !(comp->state & CLASS_LINKED))
1067 if (!link_class(comp))
1070 /* Allocate the arraydescriptor */
1072 desc = NEW(arraydescriptor);
1075 /* c is an array of references */
1076 desc->arraytype = ARRAYTYPE_OBJECT;
1077 desc->componentsize = sizeof(void*);
1078 desc->dataoffset = OFFSET(java_objectarray_t, data);
1080 compvftbl = comp->vftbl;
1083 log_text("Component class has no vftbl");
1087 desc->componentvftbl = compvftbl;
1089 if (compvftbl->arraydesc) {
1090 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1092 if (compvftbl->arraydesc->dimension >= 255) {
1093 log_text("Creating array of dimension >255");
1097 desc->dimension = compvftbl->arraydesc->dimension + 1;
1098 desc->elementtype = compvftbl->arraydesc->elementtype;
1101 desc->elementvftbl = compvftbl;
1102 desc->dimension = 1;
1103 desc->elementtype = ARRAYTYPE_OBJECT;
1107 /* c is an array of a primitive type */
1108 switch (c->name->text[1]) {
1110 desc->arraytype = ARRAYTYPE_BOOLEAN;
1111 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1112 desc->componentsize = sizeof(u1);
1116 desc->arraytype = ARRAYTYPE_BYTE;
1117 desc->dataoffset = OFFSET(java_bytearray_t,data);
1118 desc->componentsize = sizeof(u1);
1122 desc->arraytype = ARRAYTYPE_CHAR;
1123 desc->dataoffset = OFFSET(java_chararray_t,data);
1124 desc->componentsize = sizeof(u2);
1128 desc->arraytype = ARRAYTYPE_DOUBLE;
1129 desc->dataoffset = OFFSET(java_doublearray_t,data);
1130 desc->componentsize = sizeof(double);
1134 desc->arraytype = ARRAYTYPE_FLOAT;
1135 desc->dataoffset = OFFSET(java_floatarray_t,data);
1136 desc->componentsize = sizeof(float);
1140 desc->arraytype = ARRAYTYPE_INT;
1141 desc->dataoffset = OFFSET(java_intarray_t,data);
1142 desc->componentsize = sizeof(s4);
1146 desc->arraytype = ARRAYTYPE_LONG;
1147 desc->dataoffset = OFFSET(java_longarray_t,data);
1148 desc->componentsize = sizeof(s8);
1152 desc->arraytype = ARRAYTYPE_SHORT;
1153 desc->dataoffset = OFFSET(java_shortarray_t,data);
1154 desc->componentsize = sizeof(s2);
1158 exceptions_throw_noclassdeffounderror(c->name);
1162 desc->componentvftbl = NULL;
1163 desc->elementvftbl = NULL;
1164 desc->dimension = 1;
1165 desc->elementtype = desc->arraytype;
1172 /* linker_compute_subclasses ***************************************************
1176 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1177 This function needs to take the class renumber lock and stop the
1178 world during class renumbering. The lock is used in C code which
1179 is not that performance critical. Whereas JIT code uses critical
1180 sections to atomically access the class values.
1182 *******************************************************************************/
1184 static void linker_compute_subclasses(classinfo *c)
1186 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1188 if (!(c->flags & ACC_INTERFACE)) {
1193 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1194 c->nextsub = c->super->sub;
1200 /* compute class values */
1202 linker_compute_class_values(class_java_lang_Object);
1204 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1208 /* linker_compute_class_values *************************************************
1212 *******************************************************************************/
1214 static void linker_compute_class_values(classinfo *c)
1218 c->vftbl->baseval = ++classvalue;
1223 linker_compute_class_values(subs);
1225 subs = subs->nextsub;
1228 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1232 /* linker_addinterface *********************************************************
1234 Is needed by link_class for adding a VTBL to a class. All
1235 interfaces implemented by ic are added as well.
1238 true.........everything ok
1239 false........an exception has been thrown
1241 *******************************************************************************/
1243 static bool linker_addinterface(classinfo *c, classinfo *ic)
1254 if (i >= v->interfacetablelength)
1255 vm_abort("Internal error: interfacetable overflow");
1257 /* if this interface has already been added, return immediately */
1259 if (v->interfacetable[-i] != NULL)
1262 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1263 v->interfacevftbllength[i] = 1;
1264 v->interfacetable[-i] = MNEW(methodptr, 1);
1265 v->interfacetable[-i][0] = NULL;
1268 v->interfacevftbllength[i] = ic->methodscount;
1269 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1271 #if defined(ENABLE_STATISTICS)
1273 count_vftbl_len += sizeof(methodptr) *
1274 (ic->methodscount + (ic->methodscount == 0));
1277 for (j = 0; j < ic->methodscount; j++) {
1278 for (sc = c; sc != NULL; sc = sc->super) {
1279 for (k = 0; k < sc->methodscount; k++) {
1280 m = &(sc->methods[k]);
1282 if (method_canoverwrite(m, &(ic->methods[j]))) {
1283 /* method m overwrites the (abstract) method */
1284 #if defined(ENABLE_VERIFIER)
1285 /* Add loading constraints (for the more
1286 general types of the method
1288 if (!classcache_add_constraints_for_params(
1289 c->classloader, ic->classloader,
1296 /* XXX taken from gcj */
1297 /* check for ACC_STATIC: IncompatibleClassChangeError */
1299 /* check for !ACC_PUBLIC: IllegalAccessError */
1301 /* check for ACC_ABSTRACT: AbstracMethodError,
1302 not sure about that one */
1304 v->interfacetable[-i][j] = v->table[m->vftblindex];
1310 /* If no method was found, insert the AbstractMethodError
1313 #if defined(ENABLE_JIT)
1314 # if defined(ENABLE_INTRP)
1316 v->interfacetable[-i][j] =
1317 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1320 v->interfacetable[-i][j] =
1321 (methodptr) (ptrint) &asm_abstractmethoderror;
1323 v->interfacetable[-i][j] =
1324 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1332 /* add superinterfaces of this interface */
1334 for (j = 0; j < ic->interfacescount; j++)
1335 if (!linker_addinterface(c, ic->interfaces[j]))
1344 /* class_highestinterface ******************************************************
1346 Used by the function link_class to determine the amount of memory
1347 needed for the interface table.
1349 *******************************************************************************/
1351 static s4 class_highestinterface(classinfo *c)
1357 /* check for ACC_INTERFACE bit already done in link_class_intern */
1361 for (i = 0; i < c->interfacescount; i++) {
1362 h2 = class_highestinterface(c->interfaces[i]);
1373 * These are local overrides for various environment variables in Emacs.
1374 * Please do not remove this and leave it at the end of the file, where
1375 * Emacs will automagically detect them.
1376 * ---------------------------------------------------------------------
1379 * indent-tabs-mode: t
1383 * vim:noexpandtab:sw=4:ts=4: