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/globals.hpp"
53 #include "vmcore/loader.h"
54 #include "vmcore/options.h"
55 #include "vmcore/rt-timing.h"
58 /* debugging macros ***********************************************************/
61 # define TRACELINKCLASS(c) \
63 if (opt_TraceLinkClass) { \
65 log_print("[Linking "); \
72 # define TRACELINKCLASS(c)
76 /* #include "vm/resolve.h" */
77 /* copied prototype to avoid bootstrapping problem: */
78 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
80 #if defined(ENABLE_STATISTICS)
81 # include "vmcore/statistics.h"
84 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
85 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
87 #define INLINELOG(code)
91 /* global variables ***********************************************************/
93 static s4 interfaceindex; /* sequential numbering of interfaces */
96 java_object_t *linker_classrenumber_lock;
99 /* private functions **********************************************************/
101 static classinfo *link_class_intern(classinfo *c);
102 static arraydescriptor *link_array(classinfo *c);
103 static void linker_compute_class_values(classinfo *c);
104 static void linker_compute_subclasses(classinfo *c);
105 static bool linker_addinterface(classinfo *c, classinfo *ic);
106 static s4 class_highestinterface(classinfo *c);
109 /* dummy structures for alinment checks ***************************************/
111 typedef struct dummy_alignment_long_t dummy_alignment_long_t;
112 typedef struct dummy_alignment_double_t dummy_alignment_double_t;
114 struct dummy_alignment_long_t {
119 struct dummy_alignment_double_t {
125 /* linker_init *****************************************************************
127 Initializes the linker subsystem and links classes required for the
130 *******************************************************************************/
132 void linker_preinit(void)
134 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
136 /* Check for if alignment for long and double matches what we
137 assume for the current architecture. */
139 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
140 /* Define a define here which is later checked when we use this
143 # define LINKER_ALIGNMENT_LONG_DOUBLE 4
145 if (OFFSET(dummy_alignment_long_t, l) != 4)
146 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
147 OFFSET(dummy_alignment_long_t, l), 4);
149 if (OFFSET(dummy_alignment_double_t, d) != 4)
150 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
151 OFFSET(dummy_alignment_double_t, d), 4);
154 # define LINKER_ALIGNMENT_LONG_DOUBLE 8
156 if (OFFSET(dummy_alignment_long_t, l) != 8)
157 vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
158 OFFSET(dummy_alignment_long_t, l), 8);
160 if (OFFSET(dummy_alignment_double_t, d) != 8)
161 vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
162 OFFSET(dummy_alignment_double_t, d), 8);
165 /* Reset interface index. */
169 #if defined(ENABLE_THREADS)
170 /* create the global lock object */
172 linker_classrenumber_lock = NEW(java_object_t);
174 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
177 /* Link the most basic classes. */
179 if (!link_class(class_java_lang_Object))
180 vm_abort("linker_preinit: linking java/lang/Object failed");
182 #if defined(ENABLE_JAVASE)
183 if (!link_class(class_java_lang_Cloneable))
184 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
186 if (!link_class(class_java_io_Serializable))
187 vm_abort("linker_preinit: linking java/io/Serializable failed");
192 /* linker_init *****************************************************************
194 Links all classes required in the VM.
196 *******************************************************************************/
198 void linker_init(void)
200 TRACESUBSYSTEMINITIALIZATION("linker_init");
202 /* Link java.lang.Class as first class of the system, because we
203 need it's vftbl for all other classes so we can use a class as
206 if (!link_class(class_java_lang_Class))
207 vm_abort("linker_init: linking java/lang/Class failed");
209 /* Now set the header.vftbl of all classes which were created
210 before java.lang.Class was linked. */
212 class_postset_header_vftbl();
214 /* Link primitive-type wrapping classes. */
216 #if defined(ENABLE_JAVASE)
217 if (!link_class(class_java_lang_Void))
218 vm_abort("linker_init: linking failed");
221 if (!link_class(class_java_lang_Boolean))
222 vm_abort("linker_init: linking failed");
224 if (!link_class(class_java_lang_Byte))
225 vm_abort("linker_init: linking failed");
227 if (!link_class(class_java_lang_Character))
228 vm_abort("linker_init: linking failed");
230 if (!link_class(class_java_lang_Short))
231 vm_abort("linker_init: linking failed");
233 if (!link_class(class_java_lang_Integer))
234 vm_abort("linker_init: linking failed");
236 if (!link_class(class_java_lang_Long))
237 vm_abort("linker_init: linking failed");
239 if (!link_class(class_java_lang_Float))
240 vm_abort("linker_init: linking failed");
242 if (!link_class(class_java_lang_Double))
243 vm_abort("linker_init: linking failed");
245 /* Link important system classes. */
247 if (!link_class(class_java_lang_String))
248 vm_abort("linker_init: linking java/lang/String failed");
250 #if defined(ENABLE_JAVASE)
251 if (!link_class(class_java_lang_ClassLoader))
252 vm_abort("linker_init: linking failed");
254 if (!link_class(class_java_lang_SecurityManager))
255 vm_abort("linker_init: linking failed");
258 if (!link_class(class_java_lang_System))
259 vm_abort("linker_init: linking failed");
261 if (!link_class(class_java_lang_Thread))
262 vm_abort("linker_init: linking failed");
264 #if defined(ENABLE_JAVASE)
265 if (!link_class(class_java_lang_ThreadGroup))
266 vm_abort("linker_init: linking failed");
269 if (!link_class(class_java_lang_Throwable))
270 vm_abort("linker_init: linking failed");
272 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
273 if (!link_class(class_java_lang_VMSystem))
274 vm_abort("linker_init: linking failed");
276 if (!link_class(class_java_lang_VMThread))
277 vm_abort("linker_init: linking failed");
279 if (!link_class(class_java_lang_VMThrowable))
280 vm_abort("linker_init: linking failed");
283 /* Important system exceptions. */
285 if (!link_class(class_java_lang_Exception))
286 vm_abort("linker_init: linking failed");
288 if (!link_class(class_java_lang_ClassNotFoundException))
289 vm_abort("linker_init: linking failed");
291 if (!link_class(class_java_lang_RuntimeException))
292 vm_abort("linker_init: linking failed");
294 /* some classes which may be used more often */
296 #if defined(ENABLE_JAVASE)
297 if (!link_class(class_java_lang_StackTraceElement))
298 vm_abort("linker_init: linking failed");
300 if (!link_class(class_java_lang_reflect_Constructor))
301 vm_abort("linker_init: linking failed");
303 if (!link_class(class_java_lang_reflect_Field))
304 vm_abort("linker_init: linking failed");
306 if (!link_class(class_java_lang_reflect_Method))
307 vm_abort("linker_init: linking failed");
309 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
310 if (!link_class(class_java_lang_reflect_VMConstructor))
311 vm_abort("linker_init: linking failed");
313 if (!link_class(class_java_lang_reflect_VMField))
314 vm_abort("linker_init: linking failed");
316 if (!link_class(class_java_lang_reflect_VMMethod))
317 vm_abort("linker_init: linking failed");
320 if (!link_class(class_java_security_PrivilegedAction))
321 vm_abort("linker_init: linking failed");
323 if (!link_class(class_java_util_Vector))
324 vm_abort("linker_init: linking failed");
326 if (!link_class(class_java_util_HashMap))
327 vm_abort("linker_init: linking failed");
329 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
330 if (!link_class(class_sun_reflect_MagicAccessorImpl))
331 vm_abort("linker_init: linking failed");
334 if (!link_class(arrayclass_java_lang_Object))
335 vm_abort("linker_init: linking failed");
339 /* create pseudo classes used by the typechecker */
341 /* pseudo class for Arraystubs (extends java.lang.Object) */
343 pseudo_class_Arraystub =
344 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
345 pseudo_class_Arraystub->state |= CLASS_LOADED;
346 pseudo_class_Arraystub->super = class_java_lang_Object;
348 #if defined(ENABLE_JAVASE)
350 pseudo_class_Arraystub->interfacescount = 2;
351 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
352 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
353 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
355 #elif defined(ENABLE_JAVAME_CLDC1_1)
357 pseudo_class_Arraystub->interfacescount = 0;
358 pseudo_class_Arraystub->interfaces = NULL;
361 # error unknown Java configuration
364 if (!classcache_store_unique(pseudo_class_Arraystub))
365 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
367 if (!link_class(pseudo_class_Arraystub))
368 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
370 /* pseudo class representing the null type */
372 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
373 pseudo_class_Null->state |= CLASS_LOADED;
374 pseudo_class_Null->super = class_java_lang_Object;
376 if (!classcache_store_unique(pseudo_class_Null))
377 vm_abort("linker_init: could not cache pseudo_class_Null");
379 if (!link_class(pseudo_class_Null))
380 vm_abort("linker_init: linking failed");
382 /* pseudo class representing new uninitialized objects */
384 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
385 pseudo_class_New->state |= CLASS_LOADED;
386 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
387 pseudo_class_New->super = class_java_lang_Object;
389 if (!classcache_store_unique(pseudo_class_New))
390 vm_abort("linker_init: could not cache pseudo_class_New");
392 /* Correct vftbl-entries (retarded loading and linking of class
393 java/lang/String). */
395 stringtable_update();
399 /* link_class ******************************************************************
401 Wrapper function for link_class_intern to ease monitor enter/exit
402 and exception handling.
404 *******************************************************************************/
406 classinfo *link_class(classinfo *c)
409 #if defined(ENABLE_RT_TIMING)
410 struct timespec time_start, time_end;
413 RT_TIMING_GET_TIME(time_start);
416 exceptions_throw_nullpointerexception();
420 LOCK_MONITOR_ENTER(c);
422 /* Maybe the class is currently linking or is already linked.*/
424 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
425 LOCK_MONITOR_EXIT(c);
430 #if defined(ENABLE_STATISTICS)
433 if (opt_getcompilingtime)
434 compilingtime_stop();
436 if (opt_getloadingtime)
440 /* call the internal function */
442 r = link_class_intern(c);
444 /* If return value is NULL, we had a problem and the class is not
448 c->state &= ~CLASS_LINKING;
450 #if defined(ENABLE_STATISTICS)
453 if (opt_getloadingtime)
456 if (opt_getcompilingtime)
457 compilingtime_start();
460 LOCK_MONITOR_EXIT(c);
462 RT_TIMING_GET_TIME(time_end);
464 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
470 /* linker_overwrite_method *****************************************************
472 Overwrite a method with another one, update method flags and check
476 mg................the general method being overwritten
477 ms................the overwriting (more specialized) method
478 wl................worklist where to add invalidated methods
481 true..............everything ok
482 false.............an exception has been thrown
484 *******************************************************************************/
486 static bool linker_overwrite_method(methodinfo *mg,
488 method_worklist **wl)
496 /* overriding a final method is illegal */
498 if (mg->flags & ACC_FINAL) {
499 exceptions_throw_verifyerror(mg, "Overriding final method");
503 /* method ms overwrites method mg */
505 #if defined(ENABLE_VERIFIER)
506 /* Add loading constraints (for the more general types of method mg). */
507 /* Not for <init>, as it is not invoked virtually. */
509 if ((ms->name != utf_init)
510 && !classcache_add_constraints_for_params(
511 cs->classloader, cg->classloader, mg))
517 /* inherit the vftbl index, and record the overwriting */
519 ms->vftblindex = mg->vftblindex;
522 /* update flags and check assumptions */
523 /* <init> methods are a special case, as they are never dispatched dynamically */
525 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
528 #if defined(ENABLE_TLH)
529 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
530 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
531 ms->clazz->name->text, ms->name->text);
532 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
536 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
537 /* this adds another implementation */
539 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
541 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
543 method_break_assumption_monomorphic(mg, wl);
546 /* this is the first implementation */
548 mg->flags |= ACC_METHOD_IMPLEMENTED;
550 INLINELOG( printf("becomes implemented: "); method_println(mg); );
555 } while (mg != NULL);
562 /* link_class_intern ***********************************************************
564 Tries to link a class. The function calculates the length in bytes
565 that an instance of this class requires as well as the VTBL for
566 methods and interface methods.
568 *******************************************************************************/
570 static classinfo *link_class_intern(classinfo *c)
572 classinfo *super; /* super class */
573 classinfo *tc; /* temporary class variable */
574 s4 supervftbllength; /* vftbllegnth of super class */
575 s4 vftbllength; /* vftbllength of current class */
576 s4 interfacetablelength; /* interface table length */
577 vftbl_t *v; /* vftbl of current class */
578 s4 i; /* interface/method/field counter */
579 arraydescriptor *arraydesc; /* descriptor for array classes */
580 method_worklist *worklist; /* worklist for recompilation */
581 #if defined(ENABLE_RT_TIMING)
582 struct timespec time_start, time_resolving, time_compute_vftbl,
583 time_abstract, time_compute_iftbl, time_fill_vftbl,
584 time_offsets, time_fill_iftbl, time_finalizer,
588 RT_TIMING_GET_TIME(time_start);
592 /* the class must be loaded */
594 /* XXX should this be a specific exception? */
595 assert(c->state & CLASS_LOADED);
597 /* This is check in link_class. */
599 assert(!(c->state & CLASS_LINKED));
601 /* cache the self-reference of this class */
602 /* we do this for cases where the defining loader of the class */
603 /* has not yet been recorded as an initiating loader for the class */
604 /* this is needed so subsequent code can assume that self-refs */
605 /* will always resolve lazily */
606 /* No need to do it for the bootloader - it is always registered */
607 /* as initiating loader for the classes it loads. */
609 classcache_store(c->classloader,c,false);
611 /* this class is currently linking */
613 c->state |= CLASS_LINKING;
618 /* Link the super interfaces. */
620 for (i = 0; i < c->interfacescount; i++) {
621 tc = c->interfaces[i];
623 if (!(tc->state & CLASS_LINKED))
628 /* check super class */
632 /* Check for java/lang/Object. */
634 if (c->super == NULL) {
636 c->instancesize = sizeof(java_object_t);
638 vftbllength = supervftbllength = 0;
643 /* Get super class. */
647 /* Link the super class if necessary. */
649 if (!(super->state & CLASS_LINKED))
650 if (!link_class(super))
653 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
656 c->flags |= (super->flags &
657 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
659 /* handle array classes */
661 if (c->name->text[0] == '[')
662 if (!(arraydesc = link_array(c)))
665 if (c->flags & ACC_INTERFACE)
666 c->index = interfaceindex++;
668 c->index = super->index + 1;
670 c->instancesize = super->instancesize;
672 vftbllength = supervftbllength = super->vftbl->vftbllength;
674 c->finalizer = super->finalizer;
676 RT_TIMING_GET_TIME(time_resolving);
679 /* compute vftbl length */
681 for (i = 0; i < c->methodscount; i++) {
682 methodinfo *m = &(c->methods[i]);
684 if (!(m->flags & ACC_STATIC)) { /* is instance method */
690 for (j = 0; j < tc->methodscount; j++) {
691 if (method_canoverwrite(m, &(tc->methods[j]))) {
692 if (tc->methods[j].flags & ACC_PRIVATE)
693 goto notfoundvftblindex;
695 /* package-private methods in other packages */
696 /* must not be overridden */
697 /* (see Java Language Specification 8.4.8.1) */
698 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
699 && !SAME_PACKAGE(c,tc) )
701 goto notfoundvftblindex;
704 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
707 goto foundvftblindex;
715 m->vftblindex = (vftbllength++);
720 RT_TIMING_GET_TIME(time_compute_vftbl);
723 /* Check all interfaces of an abstract class (maybe be an
724 interface too) for unimplemented methods. Such methods are
725 called miranda-methods and are marked with the ACC_MIRANDA
726 flag. VMClass.getDeclaredMethods does not return such
729 if (c->flags & ACC_ABSTRACT) {
732 s4 abstractmethodscount;
736 abstractmethodscount = 0;
738 /* check all interfaces of the abstract class */
740 for (i = 0; i < c->interfacescount; i++) {
741 ic = c->interfaces[i];
743 for (j = 0; j < ic->methodscount; j++) {
744 im = &(ic->methods[j]);
746 /* skip `<clinit>' and `<init>' */
748 if ((im->name == utf_clinit) || (im->name == utf_init))
751 for (tc = c; tc != NULL; tc = tc->super) {
752 for (k = 0; k < tc->methodscount; k++) {
753 if (method_canoverwrite(im, &(tc->methods[k])))
754 goto noabstractmethod;
758 abstractmethodscount++;
765 if (abstractmethodscount > 0) {
768 /* reallocate methods memory */
770 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
771 c->methodscount + abstractmethodscount);
773 for (i = 0; i < c->interfacescount; i++) {
774 ic = c->interfaces[i];
776 for (j = 0; j < ic->methodscount; j++) {
777 im = &(ic->methods[j]);
779 /* skip `<clinit>' and `<init>' */
781 if ((im->name == utf_clinit) || (im->name == utf_init))
784 for (tc = c; tc != NULL; tc = tc->super) {
785 for (k = 0; k < tc->methodscount; k++) {
786 if (method_canoverwrite(im, &(tc->methods[k])))
787 goto noabstractmethod2;
791 /* Copy the method found into the new c->methods
792 array and tag it as miranda-method. */
794 am = &(c->methods[c->methodscount]);
797 MCOPY(am, im, methodinfo, 1);
799 am->vftblindex = (vftbllength++);
801 am->flags |= ACC_MIRANDA;
809 RT_TIMING_GET_TIME(time_abstract);
812 #if defined(ENABLE_STATISTICS)
815 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
818 /* compute interfacetable length */
820 interfacetablelength = 0;
822 for (tc = c; tc != NULL; tc = tc->super) {
823 for (i = 0; i < tc->interfacescount; i++) {
824 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
826 if (h > interfacetablelength)
827 interfacetablelength = h;
830 RT_TIMING_GET_TIME(time_compute_iftbl);
832 /* allocate virtual function table */
834 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
835 sizeof(methodptr) * (vftbllength - 1) +
836 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
837 v = (vftbl_t *) (((methodptr *) v) +
838 (interfacetablelength - 1) * (interfacetablelength > 1));
842 v->vftbllength = vftbllength;
843 v->interfacetablelength = interfacetablelength;
844 v->arraydesc = arraydesc;
846 /* store interface index in vftbl */
848 if (c->flags & ACC_INTERFACE)
849 v->baseval = -(c->index);
851 /* copy virtual function table of super class */
853 for (i = 0; i < supervftbllength; i++)
854 v->table[i] = super->vftbl->table[i];
856 /* Fill the remaining vftbl slots with the AbstractMethodError
857 stub (all after the super class slots, because they are already
860 for (; i < vftbllength; i++) {
861 #if defined(ENABLE_JIT)
862 # if defined(ENABLE_INTRP)
864 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
867 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
869 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
873 /* add method stubs into virtual function table */
875 for (i = 0; i < c->methodscount; i++) {
876 methodinfo *m = &(c->methods[i]);
878 assert(m->stubroutine == NULL);
880 /* Don't create a compiler stub for abstract methods as they
881 throw an AbstractMethodError with the default stub in the
882 vftbl. This entry is simply copied by sub-classes. */
884 if (m->flags & ACC_ABSTRACT)
887 #if defined(ENABLE_JIT)
888 # if defined(ENABLE_INTRP)
890 m->stubroutine = intrp_createcompilerstub(m);
893 m->stubroutine = codegen_generate_stub_compiler(m);
895 m->stubroutine = intrp_createcompilerstub(m);
898 /* static methods are not in the vftbl */
900 if (m->flags & ACC_STATIC)
903 /* insert the stubroutine into the vftbl */
905 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
907 RT_TIMING_GET_TIME(time_fill_vftbl);
909 /* compute instance size and offset of each field */
911 for (i = 0; i < c->fieldscount; i++) {
913 fieldinfo *f = &(c->fields[i]);
915 if (!(f->flags & ACC_STATIC)) {
916 dsize = descriptor_typesize(f->parseddesc);
918 #if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
919 /* On some architectures and configurations we need to
920 align long (int64_t) and double fields to 4-bytes to
921 match what GCC does for struct members. We must do the
922 same as GCC here because the offsets in native header
923 structs like java_lang_Double must match the offsets of
924 the Java fields (eg. java.lang.Double.value). */
926 # if LINKER_ALIGNMENT_LONG_DOUBLE != 4
927 # error alignment of long and double is not 4
930 c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
933 # if LINKER_ALIGNMENT_LONG_DOUBLE != 8
934 # error alignment of long and double is not 8
937 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
940 f->offset = c->instancesize;
941 c->instancesize += dsize;
944 RT_TIMING_GET_TIME(time_offsets);
946 /* initialize interfacetable and interfacevftbllength */
948 v->interfacevftbllength = MNEW(s4, interfacetablelength);
950 #if defined(ENABLE_STATISTICS)
952 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
955 for (i = 0; i < interfacetablelength; i++) {
956 v->interfacevftbllength[i] = 0;
957 v->interfacetable[-i] = NULL;
962 for (tc = c; tc != NULL; tc = tc->super)
963 for (i = 0; i < tc->interfacescount; i++)
964 if (!linker_addinterface(c, tc->interfaces[i]))
967 RT_TIMING_GET_TIME(time_fill_iftbl);
969 /* add finalizer method (not for java.lang.Object) */
974 fi = class_findmethod(c, utf_finalize, utf_void__void);
977 if (!(fi->flags & ACC_STATIC))
980 RT_TIMING_GET_TIME(time_finalizer);
984 linker_compute_subclasses(c);
986 RT_TIMING_GET_TIME(time_subclasses);
988 /* revert the linking state and class is linked */
990 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
994 /* XXX must this also be done in case of exception? */
996 while (worklist != NULL) {
997 method_worklist *wi = worklist;
999 worklist = worklist->next;
1001 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
1002 jit_invalidate_code(wi->m);
1004 /* XXX put worklist into dump memory? */
1005 FREE(wi, method_worklist);
1008 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
1009 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
1010 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
1011 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
1012 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
1013 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
1014 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
1015 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
1016 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
1018 /* just return c to show that we didn't had a problem */
1024 /* link_array ******************************************************************
1026 This function is called by link_class to create the arraydescriptor
1029 This function returns NULL if the array cannot be linked because
1030 the component type has not been linked yet.
1032 *******************************************************************************/
1034 static arraydescriptor *link_array(classinfo *c)
1038 arraydescriptor *desc;
1043 namelen = c->name->blength;
1045 /* Check the component type */
1047 switch (c->name->text[1]) {
1049 /* c is an array of arrays. */
1050 u = utf_new(c->name->text + 1, namelen - 1);
1051 if (!(comp = load_class_from_classloader(u, c->classloader)))
1056 /* c is an array of objects. */
1057 u = utf_new(c->name->text + 2, namelen - 3);
1058 if (!(comp = load_class_from_classloader(u, c->classloader)))
1063 /* If the component type has not been linked, link it now */
1065 assert(!comp || (comp->state & CLASS_LOADED));
1067 if (comp && !(comp->state & CLASS_LINKED))
1068 if (!link_class(comp))
1071 /* Allocate the arraydescriptor */
1073 desc = NEW(arraydescriptor);
1076 /* c is an array of references */
1077 desc->arraytype = ARRAYTYPE_OBJECT;
1078 desc->componentsize = sizeof(void*);
1079 desc->dataoffset = OFFSET(java_objectarray_t, data);
1081 compvftbl = comp->vftbl;
1084 log_text("Component class has no vftbl");
1088 desc->componentvftbl = compvftbl;
1090 if (compvftbl->arraydesc) {
1091 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1093 if (compvftbl->arraydesc->dimension >= 255) {
1094 log_text("Creating array of dimension >255");
1098 desc->dimension = compvftbl->arraydesc->dimension + 1;
1099 desc->elementtype = compvftbl->arraydesc->elementtype;
1102 desc->elementvftbl = compvftbl;
1103 desc->dimension = 1;
1104 desc->elementtype = ARRAYTYPE_OBJECT;
1108 /* c is an array of a primitive type */
1109 switch (c->name->text[1]) {
1111 desc->arraytype = ARRAYTYPE_BOOLEAN;
1112 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1113 desc->componentsize = sizeof(u1);
1117 desc->arraytype = ARRAYTYPE_BYTE;
1118 desc->dataoffset = OFFSET(java_bytearray_t,data);
1119 desc->componentsize = sizeof(u1);
1123 desc->arraytype = ARRAYTYPE_CHAR;
1124 desc->dataoffset = OFFSET(java_chararray_t,data);
1125 desc->componentsize = sizeof(u2);
1129 desc->arraytype = ARRAYTYPE_DOUBLE;
1130 desc->dataoffset = OFFSET(java_doublearray_t,data);
1131 desc->componentsize = sizeof(double);
1135 desc->arraytype = ARRAYTYPE_FLOAT;
1136 desc->dataoffset = OFFSET(java_floatarray_t,data);
1137 desc->componentsize = sizeof(float);
1141 desc->arraytype = ARRAYTYPE_INT;
1142 desc->dataoffset = OFFSET(java_intarray_t,data);
1143 desc->componentsize = sizeof(s4);
1147 desc->arraytype = ARRAYTYPE_LONG;
1148 desc->dataoffset = OFFSET(java_longarray_t,data);
1149 desc->componentsize = sizeof(s8);
1153 desc->arraytype = ARRAYTYPE_SHORT;
1154 desc->dataoffset = OFFSET(java_shortarray_t,data);
1155 desc->componentsize = sizeof(s2);
1159 exceptions_throw_noclassdeffounderror(c->name);
1163 desc->componentvftbl = NULL;
1164 desc->elementvftbl = NULL;
1165 desc->dimension = 1;
1166 desc->elementtype = desc->arraytype;
1173 /* linker_compute_subclasses ***************************************************
1177 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1178 This function needs to take the class renumber lock and stop the
1179 world during class renumbering. The lock is used in C code which
1180 is not that performance critical. Whereas JIT code uses critical
1181 sections to atomically access the class values.
1183 *******************************************************************************/
1185 static void linker_compute_subclasses(classinfo *c)
1187 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1189 if (!(c->flags & ACC_INTERFACE)) {
1194 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1195 c->nextsub = c->super->sub;
1201 /* compute class values */
1203 linker_compute_class_values(class_java_lang_Object);
1205 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1209 /* linker_compute_class_values *************************************************
1213 *******************************************************************************/
1215 static void linker_compute_class_values(classinfo *c)
1219 c->vftbl->baseval = ++classvalue;
1224 linker_compute_class_values(subs);
1226 subs = subs->nextsub;
1229 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1233 /* linker_addinterface *********************************************************
1235 Is needed by link_class for adding a VTBL to a class. All
1236 interfaces implemented by ic are added as well.
1239 true.........everything ok
1240 false........an exception has been thrown
1242 *******************************************************************************/
1244 static bool linker_addinterface(classinfo *c, classinfo *ic)
1255 if (i >= v->interfacetablelength)
1256 vm_abort("Internal error: interfacetable overflow");
1258 /* if this interface has already been added, return immediately */
1260 if (v->interfacetable[-i] != NULL)
1263 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1264 v->interfacevftbllength[i] = 1;
1265 v->interfacetable[-i] = MNEW(methodptr, 1);
1266 v->interfacetable[-i][0] = NULL;
1269 v->interfacevftbllength[i] = ic->methodscount;
1270 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1272 #if defined(ENABLE_STATISTICS)
1274 count_vftbl_len += sizeof(methodptr) *
1275 (ic->methodscount + (ic->methodscount == 0));
1278 for (j = 0; j < ic->methodscount; j++) {
1279 for (sc = c; sc != NULL; sc = sc->super) {
1280 for (k = 0; k < sc->methodscount; k++) {
1281 m = &(sc->methods[k]);
1283 if (method_canoverwrite(m, &(ic->methods[j]))) {
1284 /* method m overwrites the (abstract) method */
1285 #if defined(ENABLE_VERIFIER)
1286 /* Add loading constraints (for the more
1287 general types of the method
1289 if (!classcache_add_constraints_for_params(
1290 c->classloader, ic->classloader,
1297 /* XXX taken from gcj */
1298 /* check for ACC_STATIC: IncompatibleClassChangeError */
1300 /* check for !ACC_PUBLIC: IllegalAccessError */
1302 /* check for ACC_ABSTRACT: AbstracMethodError,
1303 not sure about that one */
1305 v->interfacetable[-i][j] = v->table[m->vftblindex];
1311 /* If no method was found, insert the AbstractMethodError
1314 #if defined(ENABLE_JIT)
1315 # if defined(ENABLE_INTRP)
1317 v->interfacetable[-i][j] =
1318 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1321 v->interfacetable[-i][j] =
1322 (methodptr) (ptrint) &asm_abstractmethoderror;
1324 v->interfacetable[-i][j] =
1325 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1333 /* add superinterfaces of this interface */
1335 for (j = 0; j < ic->interfacescount; j++)
1336 if (!linker_addinterface(c, ic->interfaces[j]))
1345 /* class_highestinterface ******************************************************
1347 Used by the function link_class to determine the amount of memory
1348 needed for the interface table.
1350 *******************************************************************************/
1352 static s4 class_highestinterface(classinfo *c)
1358 /* check for ACC_INTERFACE bit already done in link_class_intern */
1362 for (i = 0; i < c->interfacescount; i++) {
1363 h2 = class_highestinterface(c->interfaces[i]);
1374 * These are local overrides for various environment variables in Emacs.
1375 * Please do not remove this and leave it at the end of the file, where
1376 * Emacs will automagically detect them.
1377 * ---------------------------------------------------------------------
1380 * indent-tabs-mode: t
1384 * vim:noexpandtab:sw=4:ts=4: