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.hpp"
43 #include "vm/array.hpp"
44 #include "vm/class.hpp"
45 #include "vm/classcache.hpp"
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.hpp" */
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;
99 #if defined(__cplusplus)
103 /* private functions **********************************************************/
105 static classinfo *link_class_intern(classinfo *c);
106 static arraydescriptor *link_array(classinfo *c);
107 static void linker_compute_class_values(classinfo *c);
108 static void linker_compute_subclasses(classinfo *c);
109 static bool linker_addinterface(classinfo *c, classinfo *ic);
110 static s4 class_highestinterface(classinfo *c);
113 /* linker_init *****************************************************************
115 Initializes the linker subsystem and links classes required for the
118 *******************************************************************************/
120 void linker_preinit(void)
122 TRACESUBSYSTEMINITIALIZATION("linker_preinit");
124 /* Reset interface index. */
128 #if defined(ENABLE_THREADS)
129 /* create the global mutex */
131 linker_classrenumber_mutex = new Mutex();
134 /* Link the most basic classes. */
136 if (!link_class(class_java_lang_Object))
137 vm_abort("linker_preinit: linking java/lang/Object failed");
139 #if defined(ENABLE_JAVASE)
140 if (!link_class(class_java_lang_Cloneable))
141 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
143 if (!link_class(class_java_io_Serializable))
144 vm_abort("linker_preinit: linking java/io/Serializable failed");
149 /* linker_init *****************************************************************
151 Links all classes required in the VM.
153 *******************************************************************************/
155 void linker_init(void)
157 TRACESUBSYSTEMINITIALIZATION("linker_init");
159 /* Link java.lang.Class as first class of the system, because we
160 need it's vftbl for all other classes so we can use a class as
163 if (!link_class(class_java_lang_Class))
164 vm_abort("linker_init: linking java/lang/Class failed");
166 /* Now set the header.vftbl of all classes which were created
167 before java.lang.Class was linked. */
169 class_postset_header_vftbl();
171 /* Link primitive-type wrapping classes. */
173 #if defined(ENABLE_JAVASE)
174 if (!link_class(class_java_lang_Void))
175 vm_abort("linker_init: linking failed");
178 if (!link_class(class_java_lang_Boolean))
179 vm_abort("linker_init: linking failed");
181 if (!link_class(class_java_lang_Byte))
182 vm_abort("linker_init: linking failed");
184 if (!link_class(class_java_lang_Character))
185 vm_abort("linker_init: linking failed");
187 if (!link_class(class_java_lang_Short))
188 vm_abort("linker_init: linking failed");
190 if (!link_class(class_java_lang_Integer))
191 vm_abort("linker_init: linking failed");
193 if (!link_class(class_java_lang_Long))
194 vm_abort("linker_init: linking failed");
196 if (!link_class(class_java_lang_Float))
197 vm_abort("linker_init: linking failed");
199 if (!link_class(class_java_lang_Double))
200 vm_abort("linker_init: linking failed");
202 /* Link important system classes. */
204 if (!link_class(class_java_lang_String))
205 vm_abort("linker_init: linking java/lang/String failed");
207 #if defined(ENABLE_JAVASE)
208 if (!link_class(class_java_lang_ClassLoader))
209 vm_abort("linker_init: linking failed");
211 if (!link_class(class_java_lang_SecurityManager))
212 vm_abort("linker_init: linking failed");
215 if (!link_class(class_java_lang_System))
216 vm_abort("linker_init: linking failed");
218 if (!link_class(class_java_lang_Thread))
219 vm_abort("linker_init: linking failed");
221 #if defined(ENABLE_JAVASE)
222 if (!link_class(class_java_lang_ThreadGroup))
223 vm_abort("linker_init: linking failed");
226 if (!link_class(class_java_lang_Throwable))
227 vm_abort("linker_init: linking failed");
229 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
230 if (!link_class(class_java_lang_VMSystem))
231 vm_abort("linker_init: linking failed");
233 if (!link_class(class_java_lang_VMThread))
234 vm_abort("linker_init: linking failed");
236 if (!link_class(class_java_lang_VMThrowable))
237 vm_abort("linker_init: linking failed");
240 /* Important system exceptions. */
242 if (!link_class(class_java_lang_Exception))
243 vm_abort("linker_init: linking failed");
245 if (!link_class(class_java_lang_ClassNotFoundException))
246 vm_abort("linker_init: linking failed");
248 if (!link_class(class_java_lang_RuntimeException))
249 vm_abort("linker_init: linking failed");
251 /* some classes which may be used more often */
253 #if defined(ENABLE_JAVASE)
254 if (!link_class(class_java_lang_StackTraceElement))
255 vm_abort("linker_init: linking failed");
257 if (!link_class(class_java_lang_reflect_Constructor))
258 vm_abort("linker_init: linking failed");
260 if (!link_class(class_java_lang_reflect_Field))
261 vm_abort("linker_init: linking failed");
263 if (!link_class(class_java_lang_reflect_Method))
264 vm_abort("linker_init: linking failed");
266 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
267 if (!link_class(class_java_lang_reflect_VMConstructor))
268 vm_abort("linker_init: linking failed");
270 if (!link_class(class_java_lang_reflect_VMField))
271 vm_abort("linker_init: linking failed");
273 if (!link_class(class_java_lang_reflect_VMMethod))
274 vm_abort("linker_init: linking failed");
277 if (!link_class(class_java_security_PrivilegedAction))
278 vm_abort("linker_init: linking failed");
280 if (!link_class(class_java_util_Vector))
281 vm_abort("linker_init: linking failed");
283 if (!link_class(class_java_util_HashMap))
284 vm_abort("linker_init: linking failed");
286 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
287 if (!link_class(class_sun_misc_Signal))
288 vm_abort("linker_init: linking failed");
290 if (!link_class(class_sun_reflect_MagicAccessorImpl))
291 vm_abort("linker_init: linking failed");
294 if (!link_class(arrayclass_java_lang_Object))
295 vm_abort("linker_init: linking failed");
299 /* create pseudo classes used by the typechecker */
301 /* pseudo class for Arraystubs (extends java.lang.Object) */
303 pseudo_class_Arraystub =
304 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
305 pseudo_class_Arraystub->state |= CLASS_LOADED;
306 pseudo_class_Arraystub->super = class_java_lang_Object;
308 #if defined(ENABLE_JAVASE)
310 pseudo_class_Arraystub->interfacescount = 2;
311 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
312 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
313 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
315 #elif defined(ENABLE_JAVAME_CLDC1_1)
317 pseudo_class_Arraystub->interfacescount = 0;
318 pseudo_class_Arraystub->interfaces = NULL;
321 # error unknown Java configuration
324 if (!classcache_store_unique(pseudo_class_Arraystub))
325 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
327 if (!link_class(pseudo_class_Arraystub))
328 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
330 /* pseudo class representing the null type */
332 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
333 pseudo_class_Null->state |= CLASS_LOADED;
334 pseudo_class_Null->super = class_java_lang_Object;
336 if (!classcache_store_unique(pseudo_class_Null))
337 vm_abort("linker_init: could not cache pseudo_class_Null");
339 if (!link_class(pseudo_class_Null))
340 vm_abort("linker_init: linking failed");
342 /* pseudo class representing new uninitialized objects */
344 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
345 pseudo_class_New->state |= CLASS_LOADED;
346 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
347 pseudo_class_New->super = class_java_lang_Object;
349 if (!classcache_store_unique(pseudo_class_New))
350 vm_abort("linker_init: could not cache pseudo_class_New");
352 /* Correct vftbl-entries (retarded loading and linking of class
353 java/lang/String). */
355 stringtable_update();
359 /* link_class ******************************************************************
361 Wrapper function for link_class_intern to ease monitor enter/exit
362 and exception handling.
364 *******************************************************************************/
366 classinfo *link_class(classinfo *c)
369 #if defined(ENABLE_RT_TIMING)
370 struct timespec time_start, time_end;
373 RT_TIMING_GET_TIME(time_start);
376 exceptions_throw_nullpointerexception();
380 LOCK_MONITOR_ENTER(c);
382 /* Maybe the class is currently linking or is already linked.*/
384 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
385 LOCK_MONITOR_EXIT(c);
390 #if defined(ENABLE_STATISTICS)
393 if (opt_getcompilingtime)
394 compilingtime_stop();
396 if (opt_getloadingtime)
400 /* call the internal function */
402 r = link_class_intern(c);
404 /* If return value is NULL, we had a problem and the class is not
408 c->state &= ~CLASS_LINKING;
410 #if defined(ENABLE_STATISTICS)
413 if (opt_getloadingtime)
416 if (opt_getcompilingtime)
417 compilingtime_start();
420 LOCK_MONITOR_EXIT(c);
422 RT_TIMING_GET_TIME(time_end);
424 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
430 /* linker_overwrite_method *****************************************************
432 Overwrite a method with another one, update method flags and check
436 mg................the general method being overwritten
437 ms................the overwriting (more specialized) method
438 wl................worklist where to add invalidated methods
441 true..............everything ok
442 false.............an exception has been thrown
444 *******************************************************************************/
446 static bool linker_overwrite_method(methodinfo *mg,
448 method_worklist **wl)
456 /* overriding a final method is illegal */
458 if (mg->flags & ACC_FINAL) {
459 exceptions_throw_verifyerror(mg, "Overriding final method");
463 /* method ms overwrites method mg */
465 #if defined(ENABLE_VERIFIER)
466 /* Add loading constraints (for the more general types of method mg). */
467 /* Not for <init>, as it is not invoked virtually. */
469 if ((ms->name != utf_init)
470 && !classcache_add_constraints_for_params(
471 cs->classloader, cg->classloader, mg))
477 /* inherit the vftbl index, and record the overwriting */
479 ms->vftblindex = mg->vftblindex;
482 /* update flags and check assumptions */
483 /* <init> methods are a special case, as they are never dispatched dynamically */
485 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
488 #if defined(ENABLE_TLH)
489 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
490 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
491 ms->clazz->name->text, ms->name->text);
492 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
496 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
497 /* this adds another implementation */
499 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
501 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
503 method_break_assumption_monomorphic(mg, wl);
506 /* this is the first implementation */
508 mg->flags |= ACC_METHOD_IMPLEMENTED;
510 INLINELOG( printf("becomes implemented: "); method_println(mg); );
515 } while (mg != NULL);
522 /* link_class_intern ***********************************************************
524 Tries to link a class. The function calculates the length in bytes
525 that an instance of this class requires as well as the VTBL for
526 methods and interface methods.
528 *******************************************************************************/
530 static classinfo *link_class_intern(classinfo *c)
532 classinfo *super; /* super class */
533 classinfo *tc; /* temporary class variable */
534 s4 supervftbllength; /* vftbllegnth of super class */
535 s4 vftbllength; /* vftbllength of current class */
536 s4 interfacetablelength; /* interface table length */
537 vftbl_t *v; /* vftbl of current class */
538 s4 i; /* interface/method/field counter */
539 arraydescriptor *arraydesc; /* descriptor for array classes */
540 method_worklist *worklist; /* worklist for recompilation */
541 #if defined(ENABLE_RT_TIMING)
542 struct timespec time_start, time_resolving, time_compute_vftbl,
543 time_abstract, time_compute_iftbl, time_fill_vftbl,
544 time_offsets, time_fill_iftbl, time_finalizer,
548 RT_TIMING_GET_TIME(time_start);
552 /* the class must be loaded */
554 /* XXX should this be a specific exception? */
555 assert(c->state & CLASS_LOADED);
557 /* This is check in link_class. */
559 assert(!(c->state & CLASS_LINKED));
561 /* cache the self-reference of this class */
562 /* we do this for cases where the defining loader of the class */
563 /* has not yet been recorded as an initiating loader for the class */
564 /* this is needed so subsequent code can assume that self-refs */
565 /* will always resolve lazily */
566 /* No need to do it for the bootloader - it is always registered */
567 /* as initiating loader for the classes it loads. */
569 classcache_store(c->classloader,c,false);
571 /* this class is currently linking */
573 c->state |= CLASS_LINKING;
578 /* Link the super interfaces. */
580 for (i = 0; i < c->interfacescount; i++) {
581 tc = c->interfaces[i];
583 if (!(tc->state & CLASS_LINKED))
588 /* check super class */
592 /* Check for java/lang/Object. */
594 if (c->super == NULL) {
596 c->instancesize = sizeof(java_object_t);
598 vftbllength = supervftbllength = 0;
603 /* Get super class. */
607 /* Link the super class if necessary. */
609 if (!(super->state & CLASS_LINKED))
610 if (!link_class(super))
613 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
616 c->flags |= (super->flags &
617 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
619 /* handle array classes */
621 if (c->name->text[0] == '[')
622 if (!(arraydesc = link_array(c)))
625 if (c->flags & ACC_INTERFACE)
626 c->index = interfaceindex++;
628 c->index = super->index + 1;
630 c->instancesize = super->instancesize;
632 vftbllength = supervftbllength = super->vftbl->vftbllength;
634 c->finalizer = super->finalizer;
636 RT_TIMING_GET_TIME(time_resolving);
639 /* compute vftbl length */
641 for (i = 0; i < c->methodscount; i++) {
642 methodinfo *m = &(c->methods[i]);
644 if (!(m->flags & ACC_STATIC)) { /* is instance method */
650 for (j = 0; j < tc->methodscount; j++) {
651 if (method_canoverwrite(m, &(tc->methods[j]))) {
652 if (tc->methods[j].flags & ACC_PRIVATE)
653 goto notfoundvftblindex;
655 /* package-private methods in other packages */
656 /* must not be overridden */
657 /* (see Java Language Specification 8.4.8.1) */
658 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
659 && !SAME_PACKAGE(c,tc) )
661 goto notfoundvftblindex;
664 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
667 goto foundvftblindex;
675 m->vftblindex = (vftbllength++);
680 RT_TIMING_GET_TIME(time_compute_vftbl);
683 /* Check all interfaces of an abstract class (maybe be an
684 interface too) for unimplemented methods. Such methods are
685 called miranda-methods and are marked with the ACC_MIRANDA
686 flag. VMClass.getDeclaredMethods does not return such
689 if (c->flags & ACC_ABSTRACT) {
692 s4 abstractmethodscount;
696 abstractmethodscount = 0;
698 /* check all interfaces of the abstract class */
700 for (i = 0; i < c->interfacescount; i++) {
701 ic = c->interfaces[i];
703 for (j = 0; j < ic->methodscount; j++) {
704 im = &(ic->methods[j]);
706 /* skip `<clinit>' and `<init>' */
708 if ((im->name == utf_clinit) || (im->name == utf_init))
711 for (tc = c; tc != NULL; tc = tc->super) {
712 for (k = 0; k < tc->methodscount; k++) {
713 if (method_canoverwrite(im, &(tc->methods[k])))
714 goto noabstractmethod;
718 abstractmethodscount++;
725 if (abstractmethodscount > 0) {
728 /* reallocate methods memory */
730 c->methods = (methodinfo*) MREALLOC(c->methods, methodinfo, c->methodscount,
731 c->methodscount + abstractmethodscount);
733 for (i = 0; i < c->interfacescount; i++) {
734 ic = c->interfaces[i];
736 for (j = 0; j < ic->methodscount; j++) {
737 im = &(ic->methods[j]);
739 /* skip `<clinit>' and `<init>' */
741 if ((im->name == utf_clinit) || (im->name == utf_init))
744 for (tc = c; tc != NULL; tc = tc->super) {
745 for (k = 0; k < tc->methodscount; k++) {
746 if (method_canoverwrite(im, &(tc->methods[k])))
747 goto noabstractmethod2;
751 /* Copy the method found into the new c->methods
752 array and tag it as miranda-method. */
754 am = &(c->methods[c->methodscount]);
757 MCOPY(am, im, methodinfo, 1);
759 am->vftblindex = (vftbllength++);
761 am->flags |= ACC_MIRANDA;
769 RT_TIMING_GET_TIME(time_abstract);
772 #if defined(ENABLE_STATISTICS)
775 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
778 /* compute interfacetable length */
780 interfacetablelength = 0;
782 for (tc = c; tc != NULL; tc = tc->super) {
783 for (i = 0; i < tc->interfacescount; i++) {
784 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
786 if (h > interfacetablelength)
787 interfacetablelength = h;
790 RT_TIMING_GET_TIME(time_compute_iftbl);
792 /* allocate virtual function table */
794 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
795 sizeof(methodptr) * (vftbllength - 1) +
796 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
797 v = (vftbl_t *) (((methodptr *) v) +
798 (interfacetablelength - 1) * (interfacetablelength > 1));
802 v->vftbllength = vftbllength;
803 v->interfacetablelength = interfacetablelength;
804 v->arraydesc = arraydesc;
806 /* store interface index in vftbl */
808 if (c->flags & ACC_INTERFACE)
809 v->baseval = -(c->index);
811 /* copy virtual function table of super class */
813 for (i = 0; i < supervftbllength; i++)
814 v->table[i] = super->vftbl->table[i];
816 /* Fill the remaining vftbl slots with the AbstractMethodError
817 stub (all after the super class slots, because they are already
820 for (; i < vftbllength; i++) {
821 #if defined(ENABLE_JIT)
822 # if defined(ENABLE_INTRP)
824 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
827 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
829 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
833 /* add method stubs into virtual function table */
835 for (i = 0; i < c->methodscount; i++) {
836 methodinfo *m = &(c->methods[i]);
838 assert(m->stubroutine == NULL);
840 /* Don't create a compiler stub for abstract methods as they
841 throw an AbstractMethodError with the default stub in the
842 vftbl. This entry is simply copied by sub-classes. */
844 if (m->flags & ACC_ABSTRACT)
847 #if defined(ENABLE_JIT)
848 # if defined(ENABLE_INTRP)
850 m->stubroutine = intrp_createcompilerstub(m);
853 m->stubroutine = (u1*) CompilerStub::generate(m);
855 m->stubroutine = intrp_createcompilerstub(m);
858 /* static methods are not in the vftbl */
860 if (m->flags & ACC_STATIC)
863 /* insert the stubroutine into the vftbl */
865 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
867 RT_TIMING_GET_TIME(time_fill_vftbl);
869 /* compute instance size and offset of each field */
871 for (i = 0; i < c->fieldscount; i++) {
873 fieldinfo *f = &(c->fields[i]);
875 if (!(f->flags & ACC_STATIC)) {
876 dsize = descriptor_typesize(f->parseddesc);
877 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
878 f->offset = c->instancesize;
879 c->instancesize += dsize;
882 RT_TIMING_GET_TIME(time_offsets);
884 /* initialize interfacetable and interfacevftbllength */
886 v->interfacevftbllength = MNEW(s4, interfacetablelength);
888 #if defined(ENABLE_STATISTICS)
890 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
893 for (i = 0; i < interfacetablelength; i++) {
894 v->interfacevftbllength[i] = 0;
895 v->interfacetable[-i] = NULL;
900 for (tc = c; tc != NULL; tc = tc->super)
901 for (i = 0; i < tc->interfacescount; i++)
902 if (!linker_addinterface(c, tc->interfaces[i]))
905 RT_TIMING_GET_TIME(time_fill_iftbl);
907 /* add finalizer method (not for java.lang.Object) */
912 fi = class_findmethod(c, utf_finalize, utf_void__void);
915 if (!(fi->flags & ACC_STATIC))
918 RT_TIMING_GET_TIME(time_finalizer);
922 linker_compute_subclasses(c);
924 RT_TIMING_GET_TIME(time_subclasses);
926 /* revert the linking state and class is linked */
928 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
932 /* XXX must this also be done in case of exception? */
934 while (worklist != NULL) {
935 method_worklist *wi = worklist;
937 worklist = worklist->next;
939 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
940 jit_invalidate_code(wi->m);
942 /* XXX put worklist into dump memory? */
943 FREE(wi, method_worklist);
946 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
947 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
948 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
949 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
950 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
951 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
952 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
953 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
954 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
956 /* just return c to show that we didn't had a problem */
962 /* link_array ******************************************************************
964 This function is called by link_class to create the arraydescriptor
967 This function returns NULL if the array cannot be linked because
968 the component type has not been linked yet.
970 *******************************************************************************/
972 static arraydescriptor *link_array(classinfo *c)
976 arraydescriptor *desc;
981 namelen = c->name->blength;
983 /* Check the component type */
985 switch (c->name->text[1]) {
987 /* c is an array of arrays. */
988 u = utf_new(c->name->text + 1, namelen - 1);
989 if (!(comp = load_class_from_classloader(u, c->classloader)))
994 /* c is an array of objects. */
995 u = utf_new(c->name->text + 2, namelen - 3);
996 if (!(comp = load_class_from_classloader(u, c->classloader)))
1001 /* If the component type has not been linked, link it now */
1003 assert(!comp || (comp->state & CLASS_LOADED));
1005 if (comp && !(comp->state & CLASS_LINKED))
1006 if (!link_class(comp))
1009 /* Allocate the arraydescriptor */
1011 desc = NEW(arraydescriptor);
1014 /* c is an array of references */
1015 desc->arraytype = ARRAYTYPE_OBJECT;
1016 desc->componentsize = sizeof(void*);
1017 desc->dataoffset = OFFSET(java_objectarray_t, data);
1019 compvftbl = comp->vftbl;
1022 log_text("Component class has no vftbl");
1026 desc->componentvftbl = compvftbl;
1028 if (compvftbl->arraydesc) {
1029 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1031 if (compvftbl->arraydesc->dimension >= 255) {
1032 log_text("Creating array of dimension >255");
1036 desc->dimension = compvftbl->arraydesc->dimension + 1;
1037 desc->elementtype = compvftbl->arraydesc->elementtype;
1040 desc->elementvftbl = compvftbl;
1041 desc->dimension = 1;
1042 desc->elementtype = ARRAYTYPE_OBJECT;
1046 /* c is an array of a primitive type */
1047 switch (c->name->text[1]) {
1049 desc->arraytype = ARRAYTYPE_BOOLEAN;
1050 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1051 desc->componentsize = sizeof(u1);
1055 desc->arraytype = ARRAYTYPE_BYTE;
1056 desc->dataoffset = OFFSET(java_bytearray_t,data);
1057 desc->componentsize = sizeof(u1);
1061 desc->arraytype = ARRAYTYPE_CHAR;
1062 desc->dataoffset = OFFSET(java_chararray_t,data);
1063 desc->componentsize = sizeof(u2);
1067 desc->arraytype = ARRAYTYPE_DOUBLE;
1068 desc->dataoffset = OFFSET(java_doublearray_t,data);
1069 desc->componentsize = sizeof(double);
1073 desc->arraytype = ARRAYTYPE_FLOAT;
1074 desc->dataoffset = OFFSET(java_floatarray_t,data);
1075 desc->componentsize = sizeof(float);
1079 desc->arraytype = ARRAYTYPE_INT;
1080 desc->dataoffset = OFFSET(java_intarray_t,data);
1081 desc->componentsize = sizeof(s4);
1085 desc->arraytype = ARRAYTYPE_LONG;
1086 desc->dataoffset = OFFSET(java_longarray_t,data);
1087 desc->componentsize = sizeof(s8);
1091 desc->arraytype = ARRAYTYPE_SHORT;
1092 desc->dataoffset = OFFSET(java_shortarray_t,data);
1093 desc->componentsize = sizeof(s2);
1097 exceptions_throw_noclassdeffounderror(c->name);
1101 desc->componentvftbl = NULL;
1102 desc->elementvftbl = NULL;
1103 desc->dimension = 1;
1104 desc->elementtype = desc->arraytype;
1111 /* linker_compute_subclasses ***************************************************
1115 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1116 This function needs to take the class renumber lock and stop the
1117 world during class renumbering. The lock is used in C code which
1118 is not that performance critical. Whereas JIT code uses critical
1119 sections to atomically access the class values.
1121 *******************************************************************************/
1123 static void linker_compute_subclasses(classinfo *c)
1125 linker_classrenumber_mutex->lock();
1127 if (!(c->flags & ACC_INTERFACE)) {
1132 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1133 c->nextsub = c->super->sub;
1139 /* compute class values */
1141 linker_compute_class_values(class_java_lang_Object);
1143 linker_classrenumber_mutex->unlock();
1147 /* linker_compute_class_values *************************************************
1151 *******************************************************************************/
1153 static void linker_compute_class_values(classinfo *c)
1157 c->vftbl->baseval = ++classvalue;
1162 linker_compute_class_values(subs);
1164 subs = subs->nextsub;
1167 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1171 /* linker_addinterface *********************************************************
1173 Is needed by link_class for adding a VTBL to a class. All
1174 interfaces implemented by ic are added as well.
1177 true.........everything ok
1178 false........an exception has been thrown
1180 *******************************************************************************/
1182 static bool linker_addinterface(classinfo *c, classinfo *ic)
1193 if (i >= v->interfacetablelength)
1194 vm_abort("Internal error: interfacetable overflow");
1196 /* if this interface has already been added, return immediately */
1198 if (v->interfacetable[-i] != NULL)
1201 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1202 v->interfacevftbllength[i] = 1;
1203 v->interfacetable[-i] = MNEW(methodptr, 1);
1204 v->interfacetable[-i][0] = NULL;
1207 v->interfacevftbllength[i] = ic->methodscount;
1208 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1210 #if defined(ENABLE_STATISTICS)
1212 count_vftbl_len += sizeof(methodptr) *
1213 (ic->methodscount + (ic->methodscount == 0));
1216 for (j = 0; j < ic->methodscount; j++) {
1217 for (sc = c; sc != NULL; sc = sc->super) {
1218 for (k = 0; k < sc->methodscount; k++) {
1219 m = &(sc->methods[k]);
1221 if (method_canoverwrite(m, &(ic->methods[j]))) {
1222 /* method m overwrites the (abstract) method */
1223 #if defined(ENABLE_VERIFIER)
1224 /* Add loading constraints (for the more
1225 general types of the method
1227 if (!classcache_add_constraints_for_params(
1228 c->classloader, ic->classloader,
1235 /* XXX taken from gcj */
1236 /* check for ACC_STATIC: IncompatibleClassChangeError */
1238 /* check for !ACC_PUBLIC: IllegalAccessError */
1240 /* check for ACC_ABSTRACT: AbstracMethodError,
1241 not sure about that one */
1243 v->interfacetable[-i][j] = v->table[m->vftblindex];
1249 /* If no method was found, insert the AbstractMethodError
1252 #if defined(ENABLE_JIT)
1253 # if defined(ENABLE_INTRP)
1255 v->interfacetable[-i][j] =
1256 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1259 v->interfacetable[-i][j] =
1260 (methodptr) (ptrint) &asm_abstractmethoderror;
1262 v->interfacetable[-i][j] =
1263 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1271 /* add superinterfaces of this interface */
1273 for (j = 0; j < ic->interfacescount; j++)
1274 if (!linker_addinterface(c, ic->interfaces[j]))
1283 /* class_highestinterface ******************************************************
1285 Used by the function link_class to determine the amount of memory
1286 needed for the interface table.
1288 *******************************************************************************/
1290 static s4 class_highestinterface(classinfo *c)
1296 /* check for ACC_INTERFACE bit already done in link_class_intern */
1300 for (i = 0; i < c->interfacescount; i++) {
1301 h2 = class_highestinterface(c->interfaces[i]);
1310 #if defined(__cplusplus)
1315 * These are local overrides for various environment variables in Emacs.
1316 * Please do not remove this and leave it at the end of the file, where
1317 * Emacs will automagically detect them.
1318 * ---------------------------------------------------------------------
1321 * indent-tabs-mode: t
1325 * vim:noexpandtab:sw=4:ts=4: