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.hpp"
37 #include "threads/lock.hpp"
38 #include "threads/mutex.hpp"
40 #include "toolbox/logging.h"
42 #include "vm/access.h"
43 #include "vm/array.hpp"
45 #include "vm/classcache.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/globals.hpp"
48 #include "vm/loader.hpp"
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"
56 #include "vm/jit/stubs.hpp"
59 /* debugging macros ***********************************************************/
62 # define TRACELINKCLASS(c) \
64 if (opt_TraceLinkClass) { \
66 log_print("[Linking "); \
73 # define TRACELINKCLASS(c)
77 /* #include "vm/resolve.h" */
78 /* copied prototype to avoid bootstrapping problem: */
79 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
81 #if defined(ENABLE_STATISTICS)
82 # include "vm/statistics.h"
85 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
86 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
88 #define INLINELOG(code)
92 /* global variables ***********************************************************/
94 static s4 interfaceindex; /* sequential numbering of interfaces */
97 Mutex *linker_classrenumber_mutex;
100 /* private functions **********************************************************/
102 static classinfo *link_class_intern(classinfo *c);
103 static arraydescriptor *link_array(classinfo *c);
104 static void linker_compute_class_values(classinfo *c);
105 static void linker_compute_subclasses(classinfo *c);
106 static bool linker_addinterface(classinfo *c, classinfo *ic);
107 static s4 class_highestinterface(classinfo *c);
110 /* linker_init *****************************************************************
112 Initializes the linker subsystem and links classes required for the
115 *******************************************************************************/
117 void linker_preinit(void)
119 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
121 /* Reset interface index. */
125 #if defined(ENABLE_THREADS)
126 /* create the global mutex */
128 linker_classrenumber_mutex = Mutex_new();
131 /* Link the most basic classes. */
133 if (!link_class(class_java_lang_Object))
134 vm_abort("linker_preinit: linking java/lang/Object failed");
136 #if defined(ENABLE_JAVASE)
137 if (!link_class(class_java_lang_Cloneable))
138 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
140 if (!link_class(class_java_io_Serializable))
141 vm_abort("linker_preinit: linking java/io/Serializable failed");
146 /* linker_init *****************************************************************
148 Links all classes required in the VM.
150 *******************************************************************************/
152 void linker_init(void)
154 TRACESUBSYSTEMINITIALIZATION("linker_init");
156 /* Link java.lang.Class as first class of the system, because we
157 need it's vftbl for all other classes so we can use a class as
160 if (!link_class(class_java_lang_Class))
161 vm_abort("linker_init: linking java/lang/Class failed");
163 /* Now set the header.vftbl of all classes which were created
164 before java.lang.Class was linked. */
166 class_postset_header_vftbl();
168 /* Link primitive-type wrapping classes. */
170 #if defined(ENABLE_JAVASE)
171 if (!link_class(class_java_lang_Void))
172 vm_abort("linker_init: linking failed");
175 if (!link_class(class_java_lang_Boolean))
176 vm_abort("linker_init: linking failed");
178 if (!link_class(class_java_lang_Byte))
179 vm_abort("linker_init: linking failed");
181 if (!link_class(class_java_lang_Character))
182 vm_abort("linker_init: linking failed");
184 if (!link_class(class_java_lang_Short))
185 vm_abort("linker_init: linking failed");
187 if (!link_class(class_java_lang_Integer))
188 vm_abort("linker_init: linking failed");
190 if (!link_class(class_java_lang_Long))
191 vm_abort("linker_init: linking failed");
193 if (!link_class(class_java_lang_Float))
194 vm_abort("linker_init: linking failed");
196 if (!link_class(class_java_lang_Double))
197 vm_abort("linker_init: linking failed");
199 /* Link important system classes. */
201 if (!link_class(class_java_lang_String))
202 vm_abort("linker_init: linking java/lang/String failed");
204 #if defined(ENABLE_JAVASE)
205 if (!link_class(class_java_lang_ClassLoader))
206 vm_abort("linker_init: linking failed");
208 if (!link_class(class_java_lang_SecurityManager))
209 vm_abort("linker_init: linking failed");
212 if (!link_class(class_java_lang_System))
213 vm_abort("linker_init: linking failed");
215 if (!link_class(class_java_lang_Thread))
216 vm_abort("linker_init: linking failed");
218 #if defined(ENABLE_JAVASE)
219 if (!link_class(class_java_lang_ThreadGroup))
220 vm_abort("linker_init: linking failed");
223 if (!link_class(class_java_lang_Throwable))
224 vm_abort("linker_init: linking failed");
226 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
227 if (!link_class(class_java_lang_VMSystem))
228 vm_abort("linker_init: linking failed");
230 if (!link_class(class_java_lang_VMThread))
231 vm_abort("linker_init: linking failed");
233 if (!link_class(class_java_lang_VMThrowable))
234 vm_abort("linker_init: linking failed");
237 /* Important system exceptions. */
239 if (!link_class(class_java_lang_Exception))
240 vm_abort("linker_init: linking failed");
242 if (!link_class(class_java_lang_ClassNotFoundException))
243 vm_abort("linker_init: linking failed");
245 if (!link_class(class_java_lang_RuntimeException))
246 vm_abort("linker_init: linking failed");
248 /* some classes which may be used more often */
250 #if defined(ENABLE_JAVASE)
251 if (!link_class(class_java_lang_StackTraceElement))
252 vm_abort("linker_init: linking failed");
254 if (!link_class(class_java_lang_reflect_Constructor))
255 vm_abort("linker_init: linking failed");
257 if (!link_class(class_java_lang_reflect_Field))
258 vm_abort("linker_init: linking failed");
260 if (!link_class(class_java_lang_reflect_Method))
261 vm_abort("linker_init: linking failed");
263 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
264 if (!link_class(class_java_lang_reflect_VMConstructor))
265 vm_abort("linker_init: linking failed");
267 if (!link_class(class_java_lang_reflect_VMField))
268 vm_abort("linker_init: linking failed");
270 if (!link_class(class_java_lang_reflect_VMMethod))
271 vm_abort("linker_init: linking failed");
274 if (!link_class(class_java_security_PrivilegedAction))
275 vm_abort("linker_init: linking failed");
277 if (!link_class(class_java_util_Vector))
278 vm_abort("linker_init: linking failed");
280 if (!link_class(class_java_util_HashMap))
281 vm_abort("linker_init: linking failed");
283 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
284 if (!link_class(class_sun_misc_Signal))
285 vm_abort("linker_init: linking failed");
287 if (!link_class(class_sun_reflect_MagicAccessorImpl))
288 vm_abort("linker_init: linking failed");
291 if (!link_class(arrayclass_java_lang_Object))
292 vm_abort("linker_init: linking failed");
296 /* create pseudo classes used by the typechecker */
298 /* pseudo class for Arraystubs (extends java.lang.Object) */
300 pseudo_class_Arraystub =
301 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
302 pseudo_class_Arraystub->state |= CLASS_LOADED;
303 pseudo_class_Arraystub->super = class_java_lang_Object;
305 #if defined(ENABLE_JAVASE)
307 pseudo_class_Arraystub->interfacescount = 2;
308 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
309 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
310 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
312 #elif defined(ENABLE_JAVAME_CLDC1_1)
314 pseudo_class_Arraystub->interfacescount = 0;
315 pseudo_class_Arraystub->interfaces = NULL;
318 # error unknown Java configuration
321 if (!classcache_store_unique(pseudo_class_Arraystub))
322 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
324 if (!link_class(pseudo_class_Arraystub))
325 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
327 /* pseudo class representing the null type */
329 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
330 pseudo_class_Null->state |= CLASS_LOADED;
331 pseudo_class_Null->super = class_java_lang_Object;
333 if (!classcache_store_unique(pseudo_class_Null))
334 vm_abort("linker_init: could not cache pseudo_class_Null");
336 if (!link_class(pseudo_class_Null))
337 vm_abort("linker_init: linking failed");
339 /* pseudo class representing new uninitialized objects */
341 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
342 pseudo_class_New->state |= CLASS_LOADED;
343 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
344 pseudo_class_New->super = class_java_lang_Object;
346 if (!classcache_store_unique(pseudo_class_New))
347 vm_abort("linker_init: could not cache pseudo_class_New");
349 /* Correct vftbl-entries (retarded loading and linking of class
350 java/lang/String). */
352 stringtable_update();
356 /* link_class ******************************************************************
358 Wrapper function for link_class_intern to ease monitor enter/exit
359 and exception handling.
361 *******************************************************************************/
363 classinfo *link_class(classinfo *c)
366 #if defined(ENABLE_RT_TIMING)
367 struct timespec time_start, time_end;
370 RT_TIMING_GET_TIME(time_start);
373 exceptions_throw_nullpointerexception();
377 LOCK_MONITOR_ENTER(c);
379 /* Maybe the class is currently linking or is already linked.*/
381 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
382 LOCK_MONITOR_EXIT(c);
387 #if defined(ENABLE_STATISTICS)
390 if (opt_getcompilingtime)
391 compilingtime_stop();
393 if (opt_getloadingtime)
397 /* call the internal function */
399 r = link_class_intern(c);
401 /* If return value is NULL, we had a problem and the class is not
405 c->state &= ~CLASS_LINKING;
407 #if defined(ENABLE_STATISTICS)
410 if (opt_getloadingtime)
413 if (opt_getcompilingtime)
414 compilingtime_start();
417 LOCK_MONITOR_EXIT(c);
419 RT_TIMING_GET_TIME(time_end);
421 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
427 /* linker_overwrite_method *****************************************************
429 Overwrite a method with another one, update method flags and check
433 mg................the general method being overwritten
434 ms................the overwriting (more specialized) method
435 wl................worklist where to add invalidated methods
438 true..............everything ok
439 false.............an exception has been thrown
441 *******************************************************************************/
443 static bool linker_overwrite_method(methodinfo *mg,
445 method_worklist **wl)
453 /* overriding a final method is illegal */
455 if (mg->flags & ACC_FINAL) {
456 exceptions_throw_verifyerror(mg, "Overriding final method");
460 /* method ms overwrites method mg */
462 #if defined(ENABLE_VERIFIER)
463 /* Add loading constraints (for the more general types of method mg). */
464 /* Not for <init>, as it is not invoked virtually. */
466 if ((ms->name != utf_init)
467 && !classcache_add_constraints_for_params(
468 cs->classloader, cg->classloader, mg))
474 /* inherit the vftbl index, and record the overwriting */
476 ms->vftblindex = mg->vftblindex;
479 /* update flags and check assumptions */
480 /* <init> methods are a special case, as they are never dispatched dynamically */
482 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
485 #if defined(ENABLE_TLH)
486 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
487 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
488 ms->clazz->name->text, ms->name->text);
489 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
493 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
494 /* this adds another implementation */
496 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
498 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
500 method_break_assumption_monomorphic(mg, wl);
503 /* this is the first implementation */
505 mg->flags |= ACC_METHOD_IMPLEMENTED;
507 INLINELOG( printf("becomes implemented: "); method_println(mg); );
512 } while (mg != NULL);
519 /* link_class_intern ***********************************************************
521 Tries to link a class. The function calculates the length in bytes
522 that an instance of this class requires as well as the VTBL for
523 methods and interface methods.
525 *******************************************************************************/
527 static classinfo *link_class_intern(classinfo *c)
529 classinfo *super; /* super class */
530 classinfo *tc; /* temporary class variable */
531 s4 supervftbllength; /* vftbllegnth of super class */
532 s4 vftbllength; /* vftbllength of current class */
533 s4 interfacetablelength; /* interface table length */
534 vftbl_t *v; /* vftbl of current class */
535 s4 i; /* interface/method/field counter */
536 arraydescriptor *arraydesc; /* descriptor for array classes */
537 method_worklist *worklist; /* worklist for recompilation */
538 #if defined(ENABLE_RT_TIMING)
539 struct timespec time_start, time_resolving, time_compute_vftbl,
540 time_abstract, time_compute_iftbl, time_fill_vftbl,
541 time_offsets, time_fill_iftbl, time_finalizer,
545 RT_TIMING_GET_TIME(time_start);
549 /* the class must be loaded */
551 /* XXX should this be a specific exception? */
552 assert(c->state & CLASS_LOADED);
554 /* This is check in link_class. */
556 assert(!(c->state & CLASS_LINKED));
558 /* cache the self-reference of this class */
559 /* we do this for cases where the defining loader of the class */
560 /* has not yet been recorded as an initiating loader for the class */
561 /* this is needed so subsequent code can assume that self-refs */
562 /* will always resolve lazily */
563 /* No need to do it for the bootloader - it is always registered */
564 /* as initiating loader for the classes it loads. */
566 classcache_store(c->classloader,c,false);
568 /* this class is currently linking */
570 c->state |= CLASS_LINKING;
575 /* Link the super interfaces. */
577 for (i = 0; i < c->interfacescount; i++) {
578 tc = c->interfaces[i];
580 if (!(tc->state & CLASS_LINKED))
585 /* check super class */
589 /* Check for java/lang/Object. */
591 if (c->super == NULL) {
593 c->instancesize = sizeof(java_object_t);
595 vftbllength = supervftbllength = 0;
600 /* Get super class. */
604 /* Link the super class if necessary. */
606 if (!(super->state & CLASS_LINKED))
607 if (!link_class(super))
610 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
613 c->flags |= (super->flags &
614 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
616 /* handle array classes */
618 if (c->name->text[0] == '[')
619 if (!(arraydesc = link_array(c)))
622 if (c->flags & ACC_INTERFACE)
623 c->index = interfaceindex++;
625 c->index = super->index + 1;
627 c->instancesize = super->instancesize;
629 vftbllength = supervftbllength = super->vftbl->vftbllength;
631 c->finalizer = super->finalizer;
633 RT_TIMING_GET_TIME(time_resolving);
636 /* compute vftbl length */
638 for (i = 0; i < c->methodscount; i++) {
639 methodinfo *m = &(c->methods[i]);
641 if (!(m->flags & ACC_STATIC)) { /* is instance method */
647 for (j = 0; j < tc->methodscount; j++) {
648 if (method_canoverwrite(m, &(tc->methods[j]))) {
649 if (tc->methods[j].flags & ACC_PRIVATE)
650 goto notfoundvftblindex;
652 /* package-private methods in other packages */
653 /* must not be overridden */
654 /* (see Java Language Specification 8.4.8.1) */
655 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
656 && !SAME_PACKAGE(c,tc) )
658 goto notfoundvftblindex;
661 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
664 goto foundvftblindex;
672 m->vftblindex = (vftbllength++);
677 RT_TIMING_GET_TIME(time_compute_vftbl);
680 /* Check all interfaces of an abstract class (maybe be an
681 interface too) for unimplemented methods. Such methods are
682 called miranda-methods and are marked with the ACC_MIRANDA
683 flag. VMClass.getDeclaredMethods does not return such
686 if (c->flags & ACC_ABSTRACT) {
689 s4 abstractmethodscount;
693 abstractmethodscount = 0;
695 /* check all interfaces of the abstract class */
697 for (i = 0; i < c->interfacescount; i++) {
698 ic = c->interfaces[i];
700 for (j = 0; j < ic->methodscount; j++) {
701 im = &(ic->methods[j]);
703 /* skip `<clinit>' and `<init>' */
705 if ((im->name == utf_clinit) || (im->name == utf_init))
708 for (tc = c; tc != NULL; tc = tc->super) {
709 for (k = 0; k < tc->methodscount; k++) {
710 if (method_canoverwrite(im, &(tc->methods[k])))
711 goto noabstractmethod;
715 abstractmethodscount++;
722 if (abstractmethodscount > 0) {
725 /* reallocate methods memory */
727 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
728 c->methodscount + abstractmethodscount);
730 for (i = 0; i < c->interfacescount; i++) {
731 ic = c->interfaces[i];
733 for (j = 0; j < ic->methodscount; j++) {
734 im = &(ic->methods[j]);
736 /* skip `<clinit>' and `<init>' */
738 if ((im->name == utf_clinit) || (im->name == utf_init))
741 for (tc = c; tc != NULL; tc = tc->super) {
742 for (k = 0; k < tc->methodscount; k++) {
743 if (method_canoverwrite(im, &(tc->methods[k])))
744 goto noabstractmethod2;
748 /* Copy the method found into the new c->methods
749 array and tag it as miranda-method. */
751 am = &(c->methods[c->methodscount]);
754 MCOPY(am, im, methodinfo, 1);
756 am->vftblindex = (vftbllength++);
758 am->flags |= ACC_MIRANDA;
766 RT_TIMING_GET_TIME(time_abstract);
769 #if defined(ENABLE_STATISTICS)
772 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
775 /* compute interfacetable length */
777 interfacetablelength = 0;
779 for (tc = c; tc != NULL; tc = tc->super) {
780 for (i = 0; i < tc->interfacescount; i++) {
781 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
783 if (h > interfacetablelength)
784 interfacetablelength = h;
787 RT_TIMING_GET_TIME(time_compute_iftbl);
789 /* allocate virtual function table */
791 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
792 sizeof(methodptr) * (vftbllength - 1) +
793 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
794 v = (vftbl_t *) (((methodptr *) v) +
795 (interfacetablelength - 1) * (interfacetablelength > 1));
799 v->vftbllength = vftbllength;
800 v->interfacetablelength = interfacetablelength;
801 v->arraydesc = arraydesc;
803 /* store interface index in vftbl */
805 if (c->flags & ACC_INTERFACE)
806 v->baseval = -(c->index);
808 /* copy virtual function table of super class */
810 for (i = 0; i < supervftbllength; i++)
811 v->table[i] = super->vftbl->table[i];
813 /* Fill the remaining vftbl slots with the AbstractMethodError
814 stub (all after the super class slots, because they are already
817 for (; i < vftbllength; i++) {
818 #if defined(ENABLE_JIT)
819 # if defined(ENABLE_INTRP)
821 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
824 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
826 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
830 /* add method stubs into virtual function table */
832 for (i = 0; i < c->methodscount; i++) {
833 methodinfo *m = &(c->methods[i]);
835 assert(m->stubroutine == NULL);
837 /* Don't create a compiler stub for abstract methods as they
838 throw an AbstractMethodError with the default stub in the
839 vftbl. This entry is simply copied by sub-classes. */
841 if (m->flags & ACC_ABSTRACT)
844 #if defined(ENABLE_JIT)
845 # if defined(ENABLE_INTRP)
847 m->stubroutine = intrp_createcompilerstub(m);
850 m->stubroutine = CompilerStub_generate(m);
852 m->stubroutine = intrp_createcompilerstub(m);
855 /* static methods are not in the vftbl */
857 if (m->flags & ACC_STATIC)
860 /* insert the stubroutine into the vftbl */
862 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
864 RT_TIMING_GET_TIME(time_fill_vftbl);
866 /* compute instance size and offset of each field */
868 for (i = 0; i < c->fieldscount; i++) {
870 fieldinfo *f = &(c->fields[i]);
872 if (!(f->flags & ACC_STATIC)) {
873 dsize = descriptor_typesize(f->parseddesc);
874 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
875 f->offset = c->instancesize;
876 c->instancesize += dsize;
879 RT_TIMING_GET_TIME(time_offsets);
881 /* initialize interfacetable and interfacevftbllength */
883 v->interfacevftbllength = MNEW(s4, interfacetablelength);
885 #if defined(ENABLE_STATISTICS)
887 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
890 for (i = 0; i < interfacetablelength; i++) {
891 v->interfacevftbllength[i] = 0;
892 v->interfacetable[-i] = NULL;
897 for (tc = c; tc != NULL; tc = tc->super)
898 for (i = 0; i < tc->interfacescount; i++)
899 if (!linker_addinterface(c, tc->interfaces[i]))
902 RT_TIMING_GET_TIME(time_fill_iftbl);
904 /* add finalizer method (not for java.lang.Object) */
909 fi = class_findmethod(c, utf_finalize, utf_void__void);
912 if (!(fi->flags & ACC_STATIC))
915 RT_TIMING_GET_TIME(time_finalizer);
919 linker_compute_subclasses(c);
921 RT_TIMING_GET_TIME(time_subclasses);
923 /* revert the linking state and class is linked */
925 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
929 /* XXX must this also be done in case of exception? */
931 while (worklist != NULL) {
932 method_worklist *wi = worklist;
934 worklist = worklist->next;
936 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
937 jit_invalidate_code(wi->m);
939 /* XXX put worklist into dump memory? */
940 FREE(wi, method_worklist);
943 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
944 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
945 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
946 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
947 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
948 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
949 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
950 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
951 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
953 /* just return c to show that we didn't had a problem */
959 /* link_array ******************************************************************
961 This function is called by link_class to create the arraydescriptor
964 This function returns NULL if the array cannot be linked because
965 the component type has not been linked yet.
967 *******************************************************************************/
969 static arraydescriptor *link_array(classinfo *c)
973 arraydescriptor *desc;
978 namelen = c->name->blength;
980 /* Check the component type */
982 switch (c->name->text[1]) {
984 /* c is an array of arrays. */
985 u = utf_new(c->name->text + 1, namelen - 1);
986 if (!(comp = load_class_from_classloader(u, c->classloader)))
991 /* c is an array of objects. */
992 u = utf_new(c->name->text + 2, namelen - 3);
993 if (!(comp = load_class_from_classloader(u, c->classloader)))
998 /* If the component type has not been linked, link it now */
1000 assert(!comp || (comp->state & CLASS_LOADED));
1002 if (comp && !(comp->state & CLASS_LINKED))
1003 if (!link_class(comp))
1006 /* Allocate the arraydescriptor */
1008 desc = NEW(arraydescriptor);
1011 /* c is an array of references */
1012 desc->arraytype = ARRAYTYPE_OBJECT;
1013 desc->componentsize = sizeof(void*);
1014 desc->dataoffset = OFFSET(java_objectarray_t, data);
1016 compvftbl = comp->vftbl;
1019 log_text("Component class has no vftbl");
1023 desc->componentvftbl = compvftbl;
1025 if (compvftbl->arraydesc) {
1026 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1028 if (compvftbl->arraydesc->dimension >= 255) {
1029 log_text("Creating array of dimension >255");
1033 desc->dimension = compvftbl->arraydesc->dimension + 1;
1034 desc->elementtype = compvftbl->arraydesc->elementtype;
1037 desc->elementvftbl = compvftbl;
1038 desc->dimension = 1;
1039 desc->elementtype = ARRAYTYPE_OBJECT;
1043 /* c is an array of a primitive type */
1044 switch (c->name->text[1]) {
1046 desc->arraytype = ARRAYTYPE_BOOLEAN;
1047 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1048 desc->componentsize = sizeof(u1);
1052 desc->arraytype = ARRAYTYPE_BYTE;
1053 desc->dataoffset = OFFSET(java_bytearray_t,data);
1054 desc->componentsize = sizeof(u1);
1058 desc->arraytype = ARRAYTYPE_CHAR;
1059 desc->dataoffset = OFFSET(java_chararray_t,data);
1060 desc->componentsize = sizeof(u2);
1064 desc->arraytype = ARRAYTYPE_DOUBLE;
1065 desc->dataoffset = OFFSET(java_doublearray_t,data);
1066 desc->componentsize = sizeof(double);
1070 desc->arraytype = ARRAYTYPE_FLOAT;
1071 desc->dataoffset = OFFSET(java_floatarray_t,data);
1072 desc->componentsize = sizeof(float);
1076 desc->arraytype = ARRAYTYPE_INT;
1077 desc->dataoffset = OFFSET(java_intarray_t,data);
1078 desc->componentsize = sizeof(s4);
1082 desc->arraytype = ARRAYTYPE_LONG;
1083 desc->dataoffset = OFFSET(java_longarray_t,data);
1084 desc->componentsize = sizeof(s8);
1088 desc->arraytype = ARRAYTYPE_SHORT;
1089 desc->dataoffset = OFFSET(java_shortarray_t,data);
1090 desc->componentsize = sizeof(s2);
1094 exceptions_throw_noclassdeffounderror(c->name);
1098 desc->componentvftbl = NULL;
1099 desc->elementvftbl = NULL;
1100 desc->dimension = 1;
1101 desc->elementtype = desc->arraytype;
1108 /* linker_compute_subclasses ***************************************************
1112 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1113 This function needs to take the class renumber lock and stop the
1114 world during class renumbering. The lock is used in C code which
1115 is not that performance critical. Whereas JIT code uses critical
1116 sections to atomically access the class values.
1118 *******************************************************************************/
1120 static void linker_compute_subclasses(classinfo *c)
1122 Mutex_lock(linker_classrenumber_mutex);
1124 if (!(c->flags & ACC_INTERFACE)) {
1129 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1130 c->nextsub = c->super->sub;
1136 /* compute class values */
1138 linker_compute_class_values(class_java_lang_Object);
1140 Mutex_unlock(linker_classrenumber_mutex);
1144 /* linker_compute_class_values *************************************************
1148 *******************************************************************************/
1150 static void linker_compute_class_values(classinfo *c)
1154 c->vftbl->baseval = ++classvalue;
1159 linker_compute_class_values(subs);
1161 subs = subs->nextsub;
1164 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1168 /* linker_addinterface *********************************************************
1170 Is needed by link_class for adding a VTBL to a class. All
1171 interfaces implemented by ic are added as well.
1174 true.........everything ok
1175 false........an exception has been thrown
1177 *******************************************************************************/
1179 static bool linker_addinterface(classinfo *c, classinfo *ic)
1190 if (i >= v->interfacetablelength)
1191 vm_abort("Internal error: interfacetable overflow");
1193 /* if this interface has already been added, return immediately */
1195 if (v->interfacetable[-i] != NULL)
1198 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1199 v->interfacevftbllength[i] = 1;
1200 v->interfacetable[-i] = MNEW(methodptr, 1);
1201 v->interfacetable[-i][0] = NULL;
1204 v->interfacevftbllength[i] = ic->methodscount;
1205 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1207 #if defined(ENABLE_STATISTICS)
1209 count_vftbl_len += sizeof(methodptr) *
1210 (ic->methodscount + (ic->methodscount == 0));
1213 for (j = 0; j < ic->methodscount; j++) {
1214 for (sc = c; sc != NULL; sc = sc->super) {
1215 for (k = 0; k < sc->methodscount; k++) {
1216 m = &(sc->methods[k]);
1218 if (method_canoverwrite(m, &(ic->methods[j]))) {
1219 /* method m overwrites the (abstract) method */
1220 #if defined(ENABLE_VERIFIER)
1221 /* Add loading constraints (for the more
1222 general types of the method
1224 if (!classcache_add_constraints_for_params(
1225 c->classloader, ic->classloader,
1232 /* XXX taken from gcj */
1233 /* check for ACC_STATIC: IncompatibleClassChangeError */
1235 /* check for !ACC_PUBLIC: IllegalAccessError */
1237 /* check for ACC_ABSTRACT: AbstracMethodError,
1238 not sure about that one */
1240 v->interfacetable[-i][j] = v->table[m->vftblindex];
1246 /* If no method was found, insert the AbstractMethodError
1249 #if defined(ENABLE_JIT)
1250 # if defined(ENABLE_INTRP)
1252 v->interfacetable[-i][j] =
1253 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1256 v->interfacetable[-i][j] =
1257 (methodptr) (ptrint) &asm_abstractmethoderror;
1259 v->interfacetable[-i][j] =
1260 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1268 /* add superinterfaces of this interface */
1270 for (j = 0; j < ic->interfacescount; j++)
1271 if (!linker_addinterface(c, ic->interfaces[j]))
1280 /* class_highestinterface ******************************************************
1282 Used by the function link_class to determine the amount of memory
1283 needed for the interface table.
1285 *******************************************************************************/
1287 static s4 class_highestinterface(classinfo *c)
1293 /* check for ACC_INTERFACE bit already done in link_class_intern */
1297 for (i = 0; i < c->interfacescount; i++) {
1298 h2 = class_highestinterface(c->interfaces[i]);
1309 * These are local overrides for various environment variables in Emacs.
1310 * Please do not remove this and leave it at the end of the file, where
1311 * Emacs will automagically detect them.
1312 * ---------------------------------------------------------------------
1315 * indent-tabs-mode: t
1319 * vim:noexpandtab:sw=4:ts=4: