1 /* src/vm/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"
38 #include "threads/mutex.hpp"
40 #include "toolbox/logging.h"
42 #include "vm/access.h"
45 #include "vm/classcache.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/globals.hpp"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/primitive.hpp"
51 #include "vm/rt-timing.h"
52 #include "vm/string.hpp"
55 #include "vm/jit/asmpart.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 "vm/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 Mutex *linker_classrenumber_mutex;
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 /* linker_init *****************************************************************
111 Initializes the linker subsystem and links classes required for the
114 *******************************************************************************/
116 void linker_preinit(void)
118 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
120 /* Reset interface index. */
124 #if defined(ENABLE_THREADS)
125 /* create the global mutex */
127 linker_classrenumber_mutex = Mutex_new();
130 /* Link the most basic classes. */
132 if (!link_class(class_java_lang_Object))
133 vm_abort("linker_preinit: linking java/lang/Object failed");
135 #if defined(ENABLE_JAVASE)
136 if (!link_class(class_java_lang_Cloneable))
137 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
139 if (!link_class(class_java_io_Serializable))
140 vm_abort("linker_preinit: linking java/io/Serializable failed");
145 /* linker_init *****************************************************************
147 Links all classes required in the VM.
149 *******************************************************************************/
151 void linker_init(void)
153 TRACESUBSYSTEMINITIALIZATION("linker_init");
155 /* Link java.lang.Class as first class of the system, because we
156 need it's vftbl for all other classes so we can use a class as
159 if (!link_class(class_java_lang_Class))
160 vm_abort("linker_init: linking java/lang/Class failed");
162 /* Now set the header.vftbl of all classes which were created
163 before java.lang.Class was linked. */
165 class_postset_header_vftbl();
167 /* Link primitive-type wrapping classes. */
169 #if defined(ENABLE_JAVASE)
170 if (!link_class(class_java_lang_Void))
171 vm_abort("linker_init: linking failed");
174 if (!link_class(class_java_lang_Boolean))
175 vm_abort("linker_init: linking failed");
177 if (!link_class(class_java_lang_Byte))
178 vm_abort("linker_init: linking failed");
180 if (!link_class(class_java_lang_Character))
181 vm_abort("linker_init: linking failed");
183 if (!link_class(class_java_lang_Short))
184 vm_abort("linker_init: linking failed");
186 if (!link_class(class_java_lang_Integer))
187 vm_abort("linker_init: linking failed");
189 if (!link_class(class_java_lang_Long))
190 vm_abort("linker_init: linking failed");
192 if (!link_class(class_java_lang_Float))
193 vm_abort("linker_init: linking failed");
195 if (!link_class(class_java_lang_Double))
196 vm_abort("linker_init: linking failed");
198 /* Link important system classes. */
200 if (!link_class(class_java_lang_String))
201 vm_abort("linker_init: linking java/lang/String failed");
203 #if defined(ENABLE_JAVASE)
204 if (!link_class(class_java_lang_ClassLoader))
205 vm_abort("linker_init: linking failed");
207 if (!link_class(class_java_lang_SecurityManager))
208 vm_abort("linker_init: linking failed");
211 if (!link_class(class_java_lang_System))
212 vm_abort("linker_init: linking failed");
214 if (!link_class(class_java_lang_Thread))
215 vm_abort("linker_init: linking failed");
217 #if defined(ENABLE_JAVASE)
218 if (!link_class(class_java_lang_ThreadGroup))
219 vm_abort("linker_init: linking failed");
222 if (!link_class(class_java_lang_Throwable))
223 vm_abort("linker_init: linking failed");
225 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
226 if (!link_class(class_java_lang_VMSystem))
227 vm_abort("linker_init: linking failed");
229 if (!link_class(class_java_lang_VMThread))
230 vm_abort("linker_init: linking failed");
232 if (!link_class(class_java_lang_VMThrowable))
233 vm_abort("linker_init: linking failed");
236 /* Important system exceptions. */
238 if (!link_class(class_java_lang_Exception))
239 vm_abort("linker_init: linking failed");
241 if (!link_class(class_java_lang_ClassNotFoundException))
242 vm_abort("linker_init: linking failed");
244 if (!link_class(class_java_lang_RuntimeException))
245 vm_abort("linker_init: linking failed");
247 /* some classes which may be used more often */
249 #if defined(ENABLE_JAVASE)
250 if (!link_class(class_java_lang_StackTraceElement))
251 vm_abort("linker_init: linking failed");
253 if (!link_class(class_java_lang_reflect_Constructor))
254 vm_abort("linker_init: linking failed");
256 if (!link_class(class_java_lang_reflect_Field))
257 vm_abort("linker_init: linking failed");
259 if (!link_class(class_java_lang_reflect_Method))
260 vm_abort("linker_init: linking failed");
262 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
263 if (!link_class(class_java_lang_reflect_VMConstructor))
264 vm_abort("linker_init: linking failed");
266 if (!link_class(class_java_lang_reflect_VMField))
267 vm_abort("linker_init: linking failed");
269 if (!link_class(class_java_lang_reflect_VMMethod))
270 vm_abort("linker_init: linking failed");
273 if (!link_class(class_java_security_PrivilegedAction))
274 vm_abort("linker_init: linking failed");
276 if (!link_class(class_java_util_Vector))
277 vm_abort("linker_init: linking failed");
279 if (!link_class(class_java_util_HashMap))
280 vm_abort("linker_init: linking failed");
282 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
283 if (!link_class(class_sun_misc_Signal))
284 vm_abort("linker_init: linking failed");
286 if (!link_class(class_sun_reflect_MagicAccessorImpl))
287 vm_abort("linker_init: linking failed");
290 if (!link_class(arrayclass_java_lang_Object))
291 vm_abort("linker_init: linking failed");
295 /* create pseudo classes used by the typechecker */
297 /* pseudo class for Arraystubs (extends java.lang.Object) */
299 pseudo_class_Arraystub =
300 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
301 pseudo_class_Arraystub->state |= CLASS_LOADED;
302 pseudo_class_Arraystub->super = class_java_lang_Object;
304 #if defined(ENABLE_JAVASE)
306 pseudo_class_Arraystub->interfacescount = 2;
307 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
308 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
309 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
311 #elif defined(ENABLE_JAVAME_CLDC1_1)
313 pseudo_class_Arraystub->interfacescount = 0;
314 pseudo_class_Arraystub->interfaces = NULL;
317 # error unknown Java configuration
320 if (!classcache_store_unique(pseudo_class_Arraystub))
321 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
323 if (!link_class(pseudo_class_Arraystub))
324 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
326 /* pseudo class representing the null type */
328 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
329 pseudo_class_Null->state |= CLASS_LOADED;
330 pseudo_class_Null->super = class_java_lang_Object;
332 if (!classcache_store_unique(pseudo_class_Null))
333 vm_abort("linker_init: could not cache pseudo_class_Null");
335 if (!link_class(pseudo_class_Null))
336 vm_abort("linker_init: linking failed");
338 /* pseudo class representing new uninitialized objects */
340 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
341 pseudo_class_New->state |= CLASS_LOADED;
342 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
343 pseudo_class_New->super = class_java_lang_Object;
345 if (!classcache_store_unique(pseudo_class_New))
346 vm_abort("linker_init: could not cache pseudo_class_New");
348 /* Correct vftbl-entries (retarded loading and linking of class
349 java/lang/String). */
351 stringtable_update();
355 /* link_class ******************************************************************
357 Wrapper function for link_class_intern to ease monitor enter/exit
358 and exception handling.
360 *******************************************************************************/
362 classinfo *link_class(classinfo *c)
365 #if defined(ENABLE_RT_TIMING)
366 struct timespec time_start, time_end;
369 RT_TIMING_GET_TIME(time_start);
372 exceptions_throw_nullpointerexception();
376 LOCK_MONITOR_ENTER(c);
378 /* Maybe the class is currently linking or is already linked.*/
380 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
381 LOCK_MONITOR_EXIT(c);
386 #if defined(ENABLE_STATISTICS)
389 if (opt_getcompilingtime)
390 compilingtime_stop();
392 if (opt_getloadingtime)
396 /* call the internal function */
398 r = link_class_intern(c);
400 /* If return value is NULL, we had a problem and the class is not
404 c->state &= ~CLASS_LINKING;
406 #if defined(ENABLE_STATISTICS)
409 if (opt_getloadingtime)
412 if (opt_getcompilingtime)
413 compilingtime_start();
416 LOCK_MONITOR_EXIT(c);
418 RT_TIMING_GET_TIME(time_end);
420 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
426 /* linker_overwrite_method *****************************************************
428 Overwrite a method with another one, update method flags and check
432 mg................the general method being overwritten
433 ms................the overwriting (more specialized) method
434 wl................worklist where to add invalidated methods
437 true..............everything ok
438 false.............an exception has been thrown
440 *******************************************************************************/
442 static bool linker_overwrite_method(methodinfo *mg,
444 method_worklist **wl)
452 /* overriding a final method is illegal */
454 if (mg->flags & ACC_FINAL) {
455 exceptions_throw_verifyerror(mg, "Overriding final method");
459 /* method ms overwrites method mg */
461 #if defined(ENABLE_VERIFIER)
462 /* Add loading constraints (for the more general types of method mg). */
463 /* Not for <init>, as it is not invoked virtually. */
465 if ((ms->name != utf_init)
466 && !classcache_add_constraints_for_params(
467 cs->classloader, cg->classloader, mg))
473 /* inherit the vftbl index, and record the overwriting */
475 ms->vftblindex = mg->vftblindex;
478 /* update flags and check assumptions */
479 /* <init> methods are a special case, as they are never dispatched dynamically */
481 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
484 #if defined(ENABLE_TLH)
485 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
486 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
487 ms->clazz->name->text, ms->name->text);
488 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
492 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
493 /* this adds another implementation */
495 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
497 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
499 method_break_assumption_monomorphic(mg, wl);
502 /* this is the first implementation */
504 mg->flags |= ACC_METHOD_IMPLEMENTED;
506 INLINELOG( printf("becomes implemented: "); method_println(mg); );
511 } while (mg != NULL);
518 /* link_class_intern ***********************************************************
520 Tries to link a class. The function calculates the length in bytes
521 that an instance of this class requires as well as the VTBL for
522 methods and interface methods.
524 *******************************************************************************/
526 static classinfo *link_class_intern(classinfo *c)
528 classinfo *super; /* super class */
529 classinfo *tc; /* temporary class variable */
530 s4 supervftbllength; /* vftbllegnth of super class */
531 s4 vftbllength; /* vftbllength of current class */
532 s4 interfacetablelength; /* interface table length */
533 vftbl_t *v; /* vftbl of current class */
534 s4 i; /* interface/method/field counter */
535 arraydescriptor *arraydesc; /* descriptor for array classes */
536 method_worklist *worklist; /* worklist for recompilation */
537 #if defined(ENABLE_RT_TIMING)
538 struct timespec time_start, time_resolving, time_compute_vftbl,
539 time_abstract, time_compute_iftbl, time_fill_vftbl,
540 time_offsets, time_fill_iftbl, time_finalizer,
544 RT_TIMING_GET_TIME(time_start);
548 /* the class must be loaded */
550 /* XXX should this be a specific exception? */
551 assert(c->state & CLASS_LOADED);
553 /* This is check in link_class. */
555 assert(!(c->state & CLASS_LINKED));
557 /* cache the self-reference of this class */
558 /* we do this for cases where the defining loader of the class */
559 /* has not yet been recorded as an initiating loader for the class */
560 /* this is needed so subsequent code can assume that self-refs */
561 /* will always resolve lazily */
562 /* No need to do it for the bootloader - it is always registered */
563 /* as initiating loader for the classes it loads. */
565 classcache_store(c->classloader,c,false);
567 /* this class is currently linking */
569 c->state |= CLASS_LINKING;
574 /* Link the super interfaces. */
576 for (i = 0; i < c->interfacescount; i++) {
577 tc = c->interfaces[i];
579 if (!(tc->state & CLASS_LINKED))
584 /* check super class */
588 /* Check for java/lang/Object. */
590 if (c->super == NULL) {
592 c->instancesize = sizeof(java_object_t);
594 vftbllength = supervftbllength = 0;
599 /* Get super class. */
603 /* Link the super class if necessary. */
605 if (!(super->state & CLASS_LINKED))
606 if (!link_class(super))
609 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
612 c->flags |= (super->flags &
613 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
615 /* handle array classes */
617 if (c->name->text[0] == '[')
618 if (!(arraydesc = link_array(c)))
621 if (c->flags & ACC_INTERFACE)
622 c->index = interfaceindex++;
624 c->index = super->index + 1;
626 c->instancesize = super->instancesize;
628 vftbllength = supervftbllength = super->vftbl->vftbllength;
630 c->finalizer = super->finalizer;
632 RT_TIMING_GET_TIME(time_resolving);
635 /* compute vftbl length */
637 for (i = 0; i < c->methodscount; i++) {
638 methodinfo *m = &(c->methods[i]);
640 if (!(m->flags & ACC_STATIC)) { /* is instance method */
646 for (j = 0; j < tc->methodscount; j++) {
647 if (method_canoverwrite(m, &(tc->methods[j]))) {
648 if (tc->methods[j].flags & ACC_PRIVATE)
649 goto notfoundvftblindex;
651 /* package-private methods in other packages */
652 /* must not be overridden */
653 /* (see Java Language Specification 8.4.8.1) */
654 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
655 && !SAME_PACKAGE(c,tc) )
657 goto notfoundvftblindex;
660 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
663 goto foundvftblindex;
671 m->vftblindex = (vftbllength++);
676 RT_TIMING_GET_TIME(time_compute_vftbl);
679 /* Check all interfaces of an abstract class (maybe be an
680 interface too) for unimplemented methods. Such methods are
681 called miranda-methods and are marked with the ACC_MIRANDA
682 flag. VMClass.getDeclaredMethods does not return such
685 if (c->flags & ACC_ABSTRACT) {
688 s4 abstractmethodscount;
692 abstractmethodscount = 0;
694 /* check all interfaces of the abstract class */
696 for (i = 0; i < c->interfacescount; i++) {
697 ic = c->interfaces[i];
699 for (j = 0; j < ic->methodscount; j++) {
700 im = &(ic->methods[j]);
702 /* skip `<clinit>' and `<init>' */
704 if ((im->name == utf_clinit) || (im->name == utf_init))
707 for (tc = c; tc != NULL; tc = tc->super) {
708 for (k = 0; k < tc->methodscount; k++) {
709 if (method_canoverwrite(im, &(tc->methods[k])))
710 goto noabstractmethod;
714 abstractmethodscount++;
721 if (abstractmethodscount > 0) {
724 /* reallocate methods memory */
726 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
727 c->methodscount + abstractmethodscount);
729 for (i = 0; i < c->interfacescount; i++) {
730 ic = c->interfaces[i];
732 for (j = 0; j < ic->methodscount; j++) {
733 im = &(ic->methods[j]);
735 /* skip `<clinit>' and `<init>' */
737 if ((im->name == utf_clinit) || (im->name == utf_init))
740 for (tc = c; tc != NULL; tc = tc->super) {
741 for (k = 0; k < tc->methodscount; k++) {
742 if (method_canoverwrite(im, &(tc->methods[k])))
743 goto noabstractmethod2;
747 /* Copy the method found into the new c->methods
748 array and tag it as miranda-method. */
750 am = &(c->methods[c->methodscount]);
753 MCOPY(am, im, methodinfo, 1);
755 am->vftblindex = (vftbllength++);
757 am->flags |= ACC_MIRANDA;
765 RT_TIMING_GET_TIME(time_abstract);
768 #if defined(ENABLE_STATISTICS)
771 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
774 /* compute interfacetable length */
776 interfacetablelength = 0;
778 for (tc = c; tc != NULL; tc = tc->super) {
779 for (i = 0; i < tc->interfacescount; i++) {
780 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
782 if (h > interfacetablelength)
783 interfacetablelength = h;
786 RT_TIMING_GET_TIME(time_compute_iftbl);
788 /* allocate virtual function table */
790 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
791 sizeof(methodptr) * (vftbllength - 1) +
792 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
793 v = (vftbl_t *) (((methodptr *) v) +
794 (interfacetablelength - 1) * (interfacetablelength > 1));
798 v->vftbllength = vftbllength;
799 v->interfacetablelength = interfacetablelength;
800 v->arraydesc = arraydesc;
802 /* store interface index in vftbl */
804 if (c->flags & ACC_INTERFACE)
805 v->baseval = -(c->index);
807 /* copy virtual function table of super class */
809 for (i = 0; i < supervftbllength; i++)
810 v->table[i] = super->vftbl->table[i];
812 /* Fill the remaining vftbl slots with the AbstractMethodError
813 stub (all after the super class slots, because they are already
816 for (; i < vftbllength; i++) {
817 #if defined(ENABLE_JIT)
818 # if defined(ENABLE_INTRP)
820 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
823 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
825 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
829 /* add method stubs into virtual function table */
831 for (i = 0; i < c->methodscount; i++) {
832 methodinfo *m = &(c->methods[i]);
834 assert(m->stubroutine == NULL);
836 /* Don't create a compiler stub for abstract methods as they
837 throw an AbstractMethodError with the default stub in the
838 vftbl. This entry is simply copied by sub-classes. */
840 if (m->flags & ACC_ABSTRACT)
843 #if defined(ENABLE_JIT)
844 # if defined(ENABLE_INTRP)
846 m->stubroutine = intrp_createcompilerstub(m);
849 m->stubroutine = codegen_generate_stub_compiler(m);
851 m->stubroutine = intrp_createcompilerstub(m);
854 /* static methods are not in the vftbl */
856 if (m->flags & ACC_STATIC)
859 /* insert the stubroutine into the vftbl */
861 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
863 RT_TIMING_GET_TIME(time_fill_vftbl);
865 /* compute instance size and offset of each field */
867 for (i = 0; i < c->fieldscount; i++) {
869 fieldinfo *f = &(c->fields[i]);
871 if (!(f->flags & ACC_STATIC)) {
872 dsize = descriptor_typesize(f->parseddesc);
873 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
874 f->offset = c->instancesize;
875 c->instancesize += dsize;
878 RT_TIMING_GET_TIME(time_offsets);
880 /* initialize interfacetable and interfacevftbllength */
882 v->interfacevftbllength = MNEW(s4, interfacetablelength);
884 #if defined(ENABLE_STATISTICS)
886 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
889 for (i = 0; i < interfacetablelength; i++) {
890 v->interfacevftbllength[i] = 0;
891 v->interfacetable[-i] = NULL;
896 for (tc = c; tc != NULL; tc = tc->super)
897 for (i = 0; i < tc->interfacescount; i++)
898 if (!linker_addinterface(c, tc->interfaces[i]))
901 RT_TIMING_GET_TIME(time_fill_iftbl);
903 /* add finalizer method (not for java.lang.Object) */
908 fi = class_findmethod(c, utf_finalize, utf_void__void);
911 if (!(fi->flags & ACC_STATIC))
914 RT_TIMING_GET_TIME(time_finalizer);
918 linker_compute_subclasses(c);
920 RT_TIMING_GET_TIME(time_subclasses);
922 /* revert the linking state and class is linked */
924 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
928 /* XXX must this also be done in case of exception? */
930 while (worklist != NULL) {
931 method_worklist *wi = worklist;
933 worklist = worklist->next;
935 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
936 jit_invalidate_code(wi->m);
938 /* XXX put worklist into dump memory? */
939 FREE(wi, method_worklist);
942 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
943 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
944 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
945 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
946 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
947 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
948 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
949 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
950 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
952 /* just return c to show that we didn't had a problem */
958 /* link_array ******************************************************************
960 This function is called by link_class to create the arraydescriptor
963 This function returns NULL if the array cannot be linked because
964 the component type has not been linked yet.
966 *******************************************************************************/
968 static arraydescriptor *link_array(classinfo *c)
972 arraydescriptor *desc;
977 namelen = c->name->blength;
979 /* Check the component type */
981 switch (c->name->text[1]) {
983 /* c is an array of arrays. */
984 u = utf_new(c->name->text + 1, namelen - 1);
985 if (!(comp = load_class_from_classloader(u, c->classloader)))
990 /* c is an array of objects. */
991 u = utf_new(c->name->text + 2, namelen - 3);
992 if (!(comp = load_class_from_classloader(u, c->classloader)))
997 /* If the component type has not been linked, link it now */
999 assert(!comp || (comp->state & CLASS_LOADED));
1001 if (comp && !(comp->state & CLASS_LINKED))
1002 if (!link_class(comp))
1005 /* Allocate the arraydescriptor */
1007 desc = NEW(arraydescriptor);
1010 /* c is an array of references */
1011 desc->arraytype = ARRAYTYPE_OBJECT;
1012 desc->componentsize = sizeof(void*);
1013 desc->dataoffset = OFFSET(java_objectarray_t, data);
1015 compvftbl = comp->vftbl;
1018 log_text("Component class has no vftbl");
1022 desc->componentvftbl = compvftbl;
1024 if (compvftbl->arraydesc) {
1025 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1027 if (compvftbl->arraydesc->dimension >= 255) {
1028 log_text("Creating array of dimension >255");
1032 desc->dimension = compvftbl->arraydesc->dimension + 1;
1033 desc->elementtype = compvftbl->arraydesc->elementtype;
1036 desc->elementvftbl = compvftbl;
1037 desc->dimension = 1;
1038 desc->elementtype = ARRAYTYPE_OBJECT;
1042 /* c is an array of a primitive type */
1043 switch (c->name->text[1]) {
1045 desc->arraytype = ARRAYTYPE_BOOLEAN;
1046 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1047 desc->componentsize = sizeof(u1);
1051 desc->arraytype = ARRAYTYPE_BYTE;
1052 desc->dataoffset = OFFSET(java_bytearray_t,data);
1053 desc->componentsize = sizeof(u1);
1057 desc->arraytype = ARRAYTYPE_CHAR;
1058 desc->dataoffset = OFFSET(java_chararray_t,data);
1059 desc->componentsize = sizeof(u2);
1063 desc->arraytype = ARRAYTYPE_DOUBLE;
1064 desc->dataoffset = OFFSET(java_doublearray_t,data);
1065 desc->componentsize = sizeof(double);
1069 desc->arraytype = ARRAYTYPE_FLOAT;
1070 desc->dataoffset = OFFSET(java_floatarray_t,data);
1071 desc->componentsize = sizeof(float);
1075 desc->arraytype = ARRAYTYPE_INT;
1076 desc->dataoffset = OFFSET(java_intarray_t,data);
1077 desc->componentsize = sizeof(s4);
1081 desc->arraytype = ARRAYTYPE_LONG;
1082 desc->dataoffset = OFFSET(java_longarray_t,data);
1083 desc->componentsize = sizeof(s8);
1087 desc->arraytype = ARRAYTYPE_SHORT;
1088 desc->dataoffset = OFFSET(java_shortarray_t,data);
1089 desc->componentsize = sizeof(s2);
1093 exceptions_throw_noclassdeffounderror(c->name);
1097 desc->componentvftbl = NULL;
1098 desc->elementvftbl = NULL;
1099 desc->dimension = 1;
1100 desc->elementtype = desc->arraytype;
1107 /* linker_compute_subclasses ***************************************************
1111 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1112 This function needs to take the class renumber lock and stop the
1113 world during class renumbering. The lock is used in C code which
1114 is not that performance critical. Whereas JIT code uses critical
1115 sections to atomically access the class values.
1117 *******************************************************************************/
1119 static void linker_compute_subclasses(classinfo *c)
1121 Mutex_lock(linker_classrenumber_mutex);
1123 if (!(c->flags & ACC_INTERFACE)) {
1128 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1129 c->nextsub = c->super->sub;
1135 /* compute class values */
1137 linker_compute_class_values(class_java_lang_Object);
1139 Mutex_unlock(linker_classrenumber_mutex);
1143 /* linker_compute_class_values *************************************************
1147 *******************************************************************************/
1149 static void linker_compute_class_values(classinfo *c)
1153 c->vftbl->baseval = ++classvalue;
1158 linker_compute_class_values(subs);
1160 subs = subs->nextsub;
1163 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1167 /* linker_addinterface *********************************************************
1169 Is needed by link_class for adding a VTBL to a class. All
1170 interfaces implemented by ic are added as well.
1173 true.........everything ok
1174 false........an exception has been thrown
1176 *******************************************************************************/
1178 static bool linker_addinterface(classinfo *c, classinfo *ic)
1189 if (i >= v->interfacetablelength)
1190 vm_abort("Internal error: interfacetable overflow");
1192 /* if this interface has already been added, return immediately */
1194 if (v->interfacetable[-i] != NULL)
1197 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1198 v->interfacevftbllength[i] = 1;
1199 v->interfacetable[-i] = MNEW(methodptr, 1);
1200 v->interfacetable[-i][0] = NULL;
1203 v->interfacevftbllength[i] = ic->methodscount;
1204 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1206 #if defined(ENABLE_STATISTICS)
1208 count_vftbl_len += sizeof(methodptr) *
1209 (ic->methodscount + (ic->methodscount == 0));
1212 for (j = 0; j < ic->methodscount; j++) {
1213 for (sc = c; sc != NULL; sc = sc->super) {
1214 for (k = 0; k < sc->methodscount; k++) {
1215 m = &(sc->methods[k]);
1217 if (method_canoverwrite(m, &(ic->methods[j]))) {
1218 /* method m overwrites the (abstract) method */
1219 #if defined(ENABLE_VERIFIER)
1220 /* Add loading constraints (for the more
1221 general types of the method
1223 if (!classcache_add_constraints_for_params(
1224 c->classloader, ic->classloader,
1231 /* XXX taken from gcj */
1232 /* check for ACC_STATIC: IncompatibleClassChangeError */
1234 /* check for !ACC_PUBLIC: IllegalAccessError */
1236 /* check for ACC_ABSTRACT: AbstracMethodError,
1237 not sure about that one */
1239 v->interfacetable[-i][j] = v->table[m->vftblindex];
1245 /* If no method was found, insert the AbstractMethodError
1248 #if defined(ENABLE_JIT)
1249 # if defined(ENABLE_INTRP)
1251 v->interfacetable[-i][j] =
1252 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1255 v->interfacetable[-i][j] =
1256 (methodptr) (ptrint) &asm_abstractmethoderror;
1258 v->interfacetable[-i][j] =
1259 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1267 /* add superinterfaces of this interface */
1269 for (j = 0; j < ic->interfacescount; j++)
1270 if (!linker_addinterface(c, ic->interfaces[j]))
1279 /* class_highestinterface ******************************************************
1281 Used by the function link_class to determine the amount of memory
1282 needed for the interface table.
1284 *******************************************************************************/
1286 static s4 class_highestinterface(classinfo *c)
1292 /* check for ACC_INTERFACE bit already done in link_class_intern */
1296 for (i = 0; i < c->interfacescount; i++) {
1297 h2 = class_highestinterface(c->interfaces[i]);
1308 * These are local overrides for various environment variables in Emacs.
1309 * Please do not remove this and leave it at the end of the file, where
1310 * Emacs will automagically detect them.
1311 * ---------------------------------------------------------------------
1314 * indent-tabs-mode: t
1318 * vim:noexpandtab:sw=4:ts=4: