1 /* src/vmcore/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "native/native.h"
37 #include "threads/lock-common.h"
39 #include "toolbox/logging.h"
41 #include "vm/access.h"
43 #include "vm/exceptions.hpp"
44 #include "vm/primitive.hpp"
45 #include "vm/string.hpp"
48 #include "vm/jit_interface.h"
50 #include "vmcore/class.h"
51 #include "vmcore/classcache.h"
52 #include "vmcore/globals.hpp"
53 #include "vmcore/loader.h"
54 #include "vmcore/options.h"
55 #include "vmcore/rt-timing.h"
58 /* debugging macros ***********************************************************/
61 # define TRACELINKCLASS(c) \
63 if (opt_TraceLinkClass) { \
65 log_print("[Linking "); \
72 # define TRACELINKCLASS(c)
76 /* #include "vm/resolve.h" */
77 /* copied prototype to avoid bootstrapping problem: */
78 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
80 #if defined(ENABLE_STATISTICS)
81 # include "vmcore/statistics.h"
84 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
85 #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
87 #define INLINELOG(code)
91 /* global variables ***********************************************************/
93 static s4 interfaceindex; /* sequential numbering of interfaces */
96 java_object_t *linker_classrenumber_lock;
99 /* private functions **********************************************************/
101 static classinfo *link_class_intern(classinfo *c);
102 static arraydescriptor *link_array(classinfo *c);
103 static void linker_compute_class_values(classinfo *c);
104 static void linker_compute_subclasses(classinfo *c);
105 static bool linker_addinterface(classinfo *c, classinfo *ic);
106 static s4 class_highestinterface(classinfo *c);
109 /* 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 lock object */
127 linker_classrenumber_lock = NEW(java_object_t);
129 LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
132 /* Link the most basic classes. */
134 if (!link_class(class_java_lang_Object))
135 vm_abort("linker_preinit: linking java/lang/Object failed");
137 #if defined(ENABLE_JAVASE)
138 if (!link_class(class_java_lang_Cloneable))
139 vm_abort("linker_preinit: linking java/lang/Cloneable failed");
141 if (!link_class(class_java_io_Serializable))
142 vm_abort("linker_preinit: linking java/io/Serializable failed");
147 /* linker_init *****************************************************************
149 Links all classes required in the VM.
151 *******************************************************************************/
153 void linker_init(void)
155 TRACESUBSYSTEMINITIALIZATION("linker_init");
157 /* Link java.lang.Class as first class of the system, because we
158 need it's vftbl for all other classes so we can use a class as
161 if (!link_class(class_java_lang_Class))
162 vm_abort("linker_init: linking java/lang/Class failed");
164 /* Now set the header.vftbl of all classes which were created
165 before java.lang.Class was linked. */
167 class_postset_header_vftbl();
169 /* Link primitive-type wrapping classes. */
171 #if defined(ENABLE_JAVASE)
172 if (!link_class(class_java_lang_Void))
173 vm_abort("linker_init: linking failed");
176 if (!link_class(class_java_lang_Boolean))
177 vm_abort("linker_init: linking failed");
179 if (!link_class(class_java_lang_Byte))
180 vm_abort("linker_init: linking failed");
182 if (!link_class(class_java_lang_Character))
183 vm_abort("linker_init: linking failed");
185 if (!link_class(class_java_lang_Short))
186 vm_abort("linker_init: linking failed");
188 if (!link_class(class_java_lang_Integer))
189 vm_abort("linker_init: linking failed");
191 if (!link_class(class_java_lang_Long))
192 vm_abort("linker_init: linking failed");
194 if (!link_class(class_java_lang_Float))
195 vm_abort("linker_init: linking failed");
197 if (!link_class(class_java_lang_Double))
198 vm_abort("linker_init: linking failed");
200 /* Link important system classes. */
202 if (!link_class(class_java_lang_String))
203 vm_abort("linker_init: linking java/lang/String failed");
205 #if defined(ENABLE_JAVASE)
206 if (!link_class(class_java_lang_ClassLoader))
207 vm_abort("linker_init: linking failed");
209 if (!link_class(class_java_lang_SecurityManager))
210 vm_abort("linker_init: linking failed");
213 if (!link_class(class_java_lang_System))
214 vm_abort("linker_init: linking failed");
216 if (!link_class(class_java_lang_Thread))
217 vm_abort("linker_init: linking failed");
219 #if defined(ENABLE_JAVASE)
220 if (!link_class(class_java_lang_ThreadGroup))
221 vm_abort("linker_init: linking failed");
224 if (!link_class(class_java_lang_Throwable))
225 vm_abort("linker_init: linking failed");
227 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
228 if (!link_class(class_java_lang_VMSystem))
229 vm_abort("linker_init: linking failed");
231 if (!link_class(class_java_lang_VMThread))
232 vm_abort("linker_init: linking failed");
234 if (!link_class(class_java_lang_VMThrowable))
235 vm_abort("linker_init: linking failed");
238 /* Important system exceptions. */
240 if (!link_class(class_java_lang_Exception))
241 vm_abort("linker_init: linking failed");
243 if (!link_class(class_java_lang_ClassNotFoundException))
244 vm_abort("linker_init: linking failed");
246 if (!link_class(class_java_lang_RuntimeException))
247 vm_abort("linker_init: linking failed");
249 /* some classes which may be used more often */
251 #if defined(ENABLE_JAVASE)
252 if (!link_class(class_java_lang_StackTraceElement))
253 vm_abort("linker_init: linking failed");
255 if (!link_class(class_java_lang_reflect_Constructor))
256 vm_abort("linker_init: linking failed");
258 if (!link_class(class_java_lang_reflect_Field))
259 vm_abort("linker_init: linking failed");
261 if (!link_class(class_java_lang_reflect_Method))
262 vm_abort("linker_init: linking failed");
264 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
265 if (!link_class(class_java_lang_reflect_VMConstructor))
266 vm_abort("linker_init: linking failed");
268 if (!link_class(class_java_lang_reflect_VMField))
269 vm_abort("linker_init: linking failed");
271 if (!link_class(class_java_lang_reflect_VMMethod))
272 vm_abort("linker_init: linking failed");
275 if (!link_class(class_java_security_PrivilegedAction))
276 vm_abort("linker_init: linking failed");
278 if (!link_class(class_java_util_Vector))
279 vm_abort("linker_init: linking failed");
281 if (!link_class(class_java_util_HashMap))
282 vm_abort("linker_init: linking failed");
284 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
285 if (!link_class(class_sun_misc_Signal))
286 vm_abort("linker_init: linking failed");
288 if (!link_class(class_sun_reflect_MagicAccessorImpl))
289 vm_abort("linker_init: linking failed");
292 if (!link_class(arrayclass_java_lang_Object))
293 vm_abort("linker_init: linking failed");
297 /* create pseudo classes used by the typechecker */
299 /* pseudo class for Arraystubs (extends java.lang.Object) */
301 pseudo_class_Arraystub =
302 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
303 pseudo_class_Arraystub->state |= CLASS_LOADED;
304 pseudo_class_Arraystub->super = class_java_lang_Object;
306 #if defined(ENABLE_JAVASE)
308 pseudo_class_Arraystub->interfacescount = 2;
309 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
310 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
311 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
313 #elif defined(ENABLE_JAVAME_CLDC1_1)
315 pseudo_class_Arraystub->interfacescount = 0;
316 pseudo_class_Arraystub->interfaces = NULL;
319 # error unknown Java configuration
322 if (!classcache_store_unique(pseudo_class_Arraystub))
323 vm_abort("linker_init: could not cache pseudo_class_Arraystub");
325 if (!link_class(pseudo_class_Arraystub))
326 vm_abort("linker_init: linking pseudo_class_Arraystub failed");
328 /* pseudo class representing the null type */
330 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
331 pseudo_class_Null->state |= CLASS_LOADED;
332 pseudo_class_Null->super = class_java_lang_Object;
334 if (!classcache_store_unique(pseudo_class_Null))
335 vm_abort("linker_init: could not cache pseudo_class_Null");
337 if (!link_class(pseudo_class_Null))
338 vm_abort("linker_init: linking failed");
340 /* pseudo class representing new uninitialized objects */
342 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
343 pseudo_class_New->state |= CLASS_LOADED;
344 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
345 pseudo_class_New->super = class_java_lang_Object;
347 if (!classcache_store_unique(pseudo_class_New))
348 vm_abort("linker_init: could not cache pseudo_class_New");
350 /* Correct vftbl-entries (retarded loading and linking of class
351 java/lang/String). */
353 stringtable_update();
357 /* link_class ******************************************************************
359 Wrapper function for link_class_intern to ease monitor enter/exit
360 and exception handling.
362 *******************************************************************************/
364 classinfo *link_class(classinfo *c)
367 #if defined(ENABLE_RT_TIMING)
368 struct timespec time_start, time_end;
371 RT_TIMING_GET_TIME(time_start);
374 exceptions_throw_nullpointerexception();
378 LOCK_MONITOR_ENTER(c);
380 /* Maybe the class is currently linking or is already linked.*/
382 if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
383 LOCK_MONITOR_EXIT(c);
388 #if defined(ENABLE_STATISTICS)
391 if (opt_getcompilingtime)
392 compilingtime_stop();
394 if (opt_getloadingtime)
398 /* call the internal function */
400 r = link_class_intern(c);
402 /* If return value is NULL, we had a problem and the class is not
406 c->state &= ~CLASS_LINKING;
408 #if defined(ENABLE_STATISTICS)
411 if (opt_getloadingtime)
414 if (opt_getcompilingtime)
415 compilingtime_start();
418 LOCK_MONITOR_EXIT(c);
420 RT_TIMING_GET_TIME(time_end);
422 RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
428 /* linker_overwrite_method *****************************************************
430 Overwrite a method with another one, update method flags and check
434 mg................the general method being overwritten
435 ms................the overwriting (more specialized) method
436 wl................worklist where to add invalidated methods
439 true..............everything ok
440 false.............an exception has been thrown
442 *******************************************************************************/
444 static bool linker_overwrite_method(methodinfo *mg,
446 method_worklist **wl)
454 /* overriding a final method is illegal */
456 if (mg->flags & ACC_FINAL) {
457 exceptions_throw_verifyerror(mg, "Overriding final method");
461 /* method ms overwrites method mg */
463 #if defined(ENABLE_VERIFIER)
464 /* Add loading constraints (for the more general types of method mg). */
465 /* Not for <init>, as it is not invoked virtually. */
467 if ((ms->name != utf_init)
468 && !classcache_add_constraints_for_params(
469 cs->classloader, cg->classloader, mg))
475 /* inherit the vftbl index, and record the overwriting */
477 ms->vftblindex = mg->vftblindex;
480 /* update flags and check assumptions */
481 /* <init> methods are a special case, as they are never dispatched dynamically */
483 if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
486 #if defined(ENABLE_TLH)
487 if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
488 printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
489 ms->clazz->name->text, ms->name->text);
490 ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
494 if (mg->flags & ACC_METHOD_IMPLEMENTED) {
495 /* this adds another implementation */
497 mg->flags &= ~ACC_METHOD_MONOMORPHIC;
499 INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
501 method_break_assumption_monomorphic(mg, wl);
504 /* this is the first implementation */
506 mg->flags |= ACC_METHOD_IMPLEMENTED;
508 INLINELOG( printf("becomes implemented: "); method_println(mg); );
513 } while (mg != NULL);
520 /* link_class_intern ***********************************************************
522 Tries to link a class. The function calculates the length in bytes
523 that an instance of this class requires as well as the VTBL for
524 methods and interface methods.
526 *******************************************************************************/
528 static classinfo *link_class_intern(classinfo *c)
530 classinfo *super; /* super class */
531 classinfo *tc; /* temporary class variable */
532 s4 supervftbllength; /* vftbllegnth of super class */
533 s4 vftbllength; /* vftbllength of current class */
534 s4 interfacetablelength; /* interface table length */
535 vftbl_t *v; /* vftbl of current class */
536 s4 i; /* interface/method/field counter */
537 arraydescriptor *arraydesc; /* descriptor for array classes */
538 method_worklist *worklist; /* worklist for recompilation */
539 #if defined(ENABLE_RT_TIMING)
540 struct timespec time_start, time_resolving, time_compute_vftbl,
541 time_abstract, time_compute_iftbl, time_fill_vftbl,
542 time_offsets, time_fill_iftbl, time_finalizer,
546 RT_TIMING_GET_TIME(time_start);
550 /* the class must be loaded */
552 /* XXX should this be a specific exception? */
553 assert(c->state & CLASS_LOADED);
555 /* This is check in link_class. */
557 assert(!(c->state & CLASS_LINKED));
559 /* cache the self-reference of this class */
560 /* we do this for cases where the defining loader of the class */
561 /* has not yet been recorded as an initiating loader for the class */
562 /* this is needed so subsequent code can assume that self-refs */
563 /* will always resolve lazily */
564 /* No need to do it for the bootloader - it is always registered */
565 /* as initiating loader for the classes it loads. */
567 classcache_store(c->classloader,c,false);
569 /* this class is currently linking */
571 c->state |= CLASS_LINKING;
576 /* Link the super interfaces. */
578 for (i = 0; i < c->interfacescount; i++) {
579 tc = c->interfaces[i];
581 if (!(tc->state & CLASS_LINKED))
586 /* check super class */
590 /* Check for java/lang/Object. */
592 if (c->super == NULL) {
594 c->instancesize = sizeof(java_object_t);
596 vftbllength = supervftbllength = 0;
601 /* Get super class. */
605 /* Link the super class if necessary. */
607 if (!(super->state & CLASS_LINKED))
608 if (!link_class(super))
611 /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
614 c->flags |= (super->flags &
615 (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
617 /* handle array classes */
619 if (c->name->text[0] == '[')
620 if (!(arraydesc = link_array(c)))
623 if (c->flags & ACC_INTERFACE)
624 c->index = interfaceindex++;
626 c->index = super->index + 1;
628 c->instancesize = super->instancesize;
630 vftbllength = supervftbllength = super->vftbl->vftbllength;
632 c->finalizer = super->finalizer;
634 RT_TIMING_GET_TIME(time_resolving);
637 /* compute vftbl length */
639 for (i = 0; i < c->methodscount; i++) {
640 methodinfo *m = &(c->methods[i]);
642 if (!(m->flags & ACC_STATIC)) { /* is instance method */
648 for (j = 0; j < tc->methodscount; j++) {
649 if (method_canoverwrite(m, &(tc->methods[j]))) {
650 if (tc->methods[j].flags & ACC_PRIVATE)
651 goto notfoundvftblindex;
653 /* package-private methods in other packages */
654 /* must not be overridden */
655 /* (see Java Language Specification 8.4.8.1) */
656 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
657 && !SAME_PACKAGE(c,tc) )
659 goto notfoundvftblindex;
662 if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
665 goto foundvftblindex;
673 m->vftblindex = (vftbllength++);
678 RT_TIMING_GET_TIME(time_compute_vftbl);
681 /* Check all interfaces of an abstract class (maybe be an
682 interface too) for unimplemented methods. Such methods are
683 called miranda-methods and are marked with the ACC_MIRANDA
684 flag. VMClass.getDeclaredMethods does not return such
687 if (c->flags & ACC_ABSTRACT) {
690 s4 abstractmethodscount;
694 abstractmethodscount = 0;
696 /* check all interfaces of the abstract class */
698 for (i = 0; i < c->interfacescount; i++) {
699 ic = c->interfaces[i];
701 for (j = 0; j < ic->methodscount; j++) {
702 im = &(ic->methods[j]);
704 /* skip `<clinit>' and `<init>' */
706 if ((im->name == utf_clinit) || (im->name == utf_init))
709 for (tc = c; tc != NULL; tc = tc->super) {
710 for (k = 0; k < tc->methodscount; k++) {
711 if (method_canoverwrite(im, &(tc->methods[k])))
712 goto noabstractmethod;
716 abstractmethodscount++;
723 if (abstractmethodscount > 0) {
726 /* reallocate methods memory */
728 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
729 c->methodscount + abstractmethodscount);
731 for (i = 0; i < c->interfacescount; i++) {
732 ic = c->interfaces[i];
734 for (j = 0; j < ic->methodscount; j++) {
735 im = &(ic->methods[j]);
737 /* skip `<clinit>' and `<init>' */
739 if ((im->name == utf_clinit) || (im->name == utf_init))
742 for (tc = c; tc != NULL; tc = tc->super) {
743 for (k = 0; k < tc->methodscount; k++) {
744 if (method_canoverwrite(im, &(tc->methods[k])))
745 goto noabstractmethod2;
749 /* Copy the method found into the new c->methods
750 array and tag it as miranda-method. */
752 am = &(c->methods[c->methodscount]);
755 MCOPY(am, im, methodinfo, 1);
757 am->vftblindex = (vftbllength++);
759 am->flags |= ACC_MIRANDA;
767 RT_TIMING_GET_TIME(time_abstract);
770 #if defined(ENABLE_STATISTICS)
773 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
776 /* compute interfacetable length */
778 interfacetablelength = 0;
780 for (tc = c; tc != NULL; tc = tc->super) {
781 for (i = 0; i < tc->interfacescount; i++) {
782 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
784 if (h > interfacetablelength)
785 interfacetablelength = h;
788 RT_TIMING_GET_TIME(time_compute_iftbl);
790 /* allocate virtual function table */
792 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
793 sizeof(methodptr) * (vftbllength - 1) +
794 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
795 v = (vftbl_t *) (((methodptr *) v) +
796 (interfacetablelength - 1) * (interfacetablelength > 1));
800 v->vftbllength = vftbllength;
801 v->interfacetablelength = interfacetablelength;
802 v->arraydesc = arraydesc;
804 /* store interface index in vftbl */
806 if (c->flags & ACC_INTERFACE)
807 v->baseval = -(c->index);
809 /* copy virtual function table of super class */
811 for (i = 0; i < supervftbllength; i++)
812 v->table[i] = super->vftbl->table[i];
814 /* Fill the remaining vftbl slots with the AbstractMethodError
815 stub (all after the super class slots, because they are already
818 for (; i < vftbllength; i++) {
819 #if defined(ENABLE_JIT)
820 # if defined(ENABLE_INTRP)
822 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
825 v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
827 v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
831 /* add method stubs into virtual function table */
833 for (i = 0; i < c->methodscount; i++) {
834 methodinfo *m = &(c->methods[i]);
836 assert(m->stubroutine == NULL);
838 /* Don't create a compiler stub for abstract methods as they
839 throw an AbstractMethodError with the default stub in the
840 vftbl. This entry is simply copied by sub-classes. */
842 if (m->flags & ACC_ABSTRACT)
845 #if defined(ENABLE_JIT)
846 # if defined(ENABLE_INTRP)
848 m->stubroutine = intrp_createcompilerstub(m);
851 m->stubroutine = codegen_generate_stub_compiler(m);
853 m->stubroutine = intrp_createcompilerstub(m);
856 /* static methods are not in the vftbl */
858 if (m->flags & ACC_STATIC)
861 /* insert the stubroutine into the vftbl */
863 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
865 RT_TIMING_GET_TIME(time_fill_vftbl);
867 /* compute instance size and offset of each field */
869 for (i = 0; i < c->fieldscount; i++) {
871 fieldinfo *f = &(c->fields[i]);
873 if (!(f->flags & ACC_STATIC)) {
874 dsize = descriptor_typesize(f->parseddesc);
875 c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
876 f->offset = c->instancesize;
877 c->instancesize += dsize;
880 RT_TIMING_GET_TIME(time_offsets);
882 /* initialize interfacetable and interfacevftbllength */
884 v->interfacevftbllength = MNEW(s4, interfacetablelength);
886 #if defined(ENABLE_STATISTICS)
888 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
891 for (i = 0; i < interfacetablelength; i++) {
892 v->interfacevftbllength[i] = 0;
893 v->interfacetable[-i] = NULL;
898 for (tc = c; tc != NULL; tc = tc->super)
899 for (i = 0; i < tc->interfacescount; i++)
900 if (!linker_addinterface(c, tc->interfaces[i]))
903 RT_TIMING_GET_TIME(time_fill_iftbl);
905 /* add finalizer method (not for java.lang.Object) */
910 fi = class_findmethod(c, utf_finalize, utf_void__void);
913 if (!(fi->flags & ACC_STATIC))
916 RT_TIMING_GET_TIME(time_finalizer);
920 linker_compute_subclasses(c);
922 RT_TIMING_GET_TIME(time_subclasses);
924 /* revert the linking state and class is linked */
926 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
930 /* XXX must this also be done in case of exception? */
932 while (worklist != NULL) {
933 method_worklist *wi = worklist;
935 worklist = worklist->next;
937 INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
938 jit_invalidate_code(wi->m);
940 /* XXX put worklist into dump memory? */
941 FREE(wi, method_worklist);
944 RT_TIMING_TIME_DIFF(time_start ,time_resolving ,RT_TIMING_LINK_RESOLVE);
945 RT_TIMING_TIME_DIFF(time_resolving ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
946 RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract ,RT_TIMING_LINK_ABSTRACT);
947 RT_TIMING_TIME_DIFF(time_abstract ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
948 RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl ,RT_TIMING_LINK_F_VFTBL);
949 RT_TIMING_TIME_DIFF(time_fill_vftbl ,time_offsets ,RT_TIMING_LINK_OFFSETS);
950 RT_TIMING_TIME_DIFF(time_offsets ,time_fill_iftbl ,RT_TIMING_LINK_F_IFTBL);
951 RT_TIMING_TIME_DIFF(time_fill_iftbl ,time_finalizer ,RT_TIMING_LINK_FINALIZER);
952 RT_TIMING_TIME_DIFF(time_finalizer ,time_subclasses ,RT_TIMING_LINK_SUBCLASS);
954 /* just return c to show that we didn't had a problem */
960 /* link_array ******************************************************************
962 This function is called by link_class to create the arraydescriptor
965 This function returns NULL if the array cannot be linked because
966 the component type has not been linked yet.
968 *******************************************************************************/
970 static arraydescriptor *link_array(classinfo *c)
974 arraydescriptor *desc;
979 namelen = c->name->blength;
981 /* Check the component type */
983 switch (c->name->text[1]) {
985 /* c is an array of arrays. */
986 u = utf_new(c->name->text + 1, namelen - 1);
987 if (!(comp = load_class_from_classloader(u, c->classloader)))
992 /* c is an array of objects. */
993 u = utf_new(c->name->text + 2, namelen - 3);
994 if (!(comp = load_class_from_classloader(u, c->classloader)))
999 /* If the component type has not been linked, link it now */
1001 assert(!comp || (comp->state & CLASS_LOADED));
1003 if (comp && !(comp->state & CLASS_LINKED))
1004 if (!link_class(comp))
1007 /* Allocate the arraydescriptor */
1009 desc = NEW(arraydescriptor);
1012 /* c is an array of references */
1013 desc->arraytype = ARRAYTYPE_OBJECT;
1014 desc->componentsize = sizeof(void*);
1015 desc->dataoffset = OFFSET(java_objectarray_t, data);
1017 compvftbl = comp->vftbl;
1020 log_text("Component class has no vftbl");
1024 desc->componentvftbl = compvftbl;
1026 if (compvftbl->arraydesc) {
1027 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1029 if (compvftbl->arraydesc->dimension >= 255) {
1030 log_text("Creating array of dimension >255");
1034 desc->dimension = compvftbl->arraydesc->dimension + 1;
1035 desc->elementtype = compvftbl->arraydesc->elementtype;
1038 desc->elementvftbl = compvftbl;
1039 desc->dimension = 1;
1040 desc->elementtype = ARRAYTYPE_OBJECT;
1044 /* c is an array of a primitive type */
1045 switch (c->name->text[1]) {
1047 desc->arraytype = ARRAYTYPE_BOOLEAN;
1048 desc->dataoffset = OFFSET(java_booleanarray_t,data);
1049 desc->componentsize = sizeof(u1);
1053 desc->arraytype = ARRAYTYPE_BYTE;
1054 desc->dataoffset = OFFSET(java_bytearray_t,data);
1055 desc->componentsize = sizeof(u1);
1059 desc->arraytype = ARRAYTYPE_CHAR;
1060 desc->dataoffset = OFFSET(java_chararray_t,data);
1061 desc->componentsize = sizeof(u2);
1065 desc->arraytype = ARRAYTYPE_DOUBLE;
1066 desc->dataoffset = OFFSET(java_doublearray_t,data);
1067 desc->componentsize = sizeof(double);
1071 desc->arraytype = ARRAYTYPE_FLOAT;
1072 desc->dataoffset = OFFSET(java_floatarray_t,data);
1073 desc->componentsize = sizeof(float);
1077 desc->arraytype = ARRAYTYPE_INT;
1078 desc->dataoffset = OFFSET(java_intarray_t,data);
1079 desc->componentsize = sizeof(s4);
1083 desc->arraytype = ARRAYTYPE_LONG;
1084 desc->dataoffset = OFFSET(java_longarray_t,data);
1085 desc->componentsize = sizeof(s8);
1089 desc->arraytype = ARRAYTYPE_SHORT;
1090 desc->dataoffset = OFFSET(java_shortarray_t,data);
1091 desc->componentsize = sizeof(s2);
1095 exceptions_throw_noclassdeffounderror(c->name);
1099 desc->componentvftbl = NULL;
1100 desc->elementvftbl = NULL;
1101 desc->dimension = 1;
1102 desc->elementtype = desc->arraytype;
1109 /* linker_compute_subclasses ***************************************************
1113 ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1114 This function needs to take the class renumber lock and stop the
1115 world during class renumbering. The lock is used in C code which
1116 is not that performance critical. Whereas JIT code uses critical
1117 sections to atomically access the class values.
1119 *******************************************************************************/
1121 static void linker_compute_subclasses(classinfo *c)
1123 LOCK_MONITOR_ENTER(linker_classrenumber_lock);
1125 if (!(c->flags & ACC_INTERFACE)) {
1130 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1131 c->nextsub = c->super->sub;
1137 /* compute class values */
1139 linker_compute_class_values(class_java_lang_Object);
1141 LOCK_MONITOR_EXIT(linker_classrenumber_lock);
1145 /* linker_compute_class_values *************************************************
1149 *******************************************************************************/
1151 static void linker_compute_class_values(classinfo *c)
1155 c->vftbl->baseval = ++classvalue;
1160 linker_compute_class_values(subs);
1162 subs = subs->nextsub;
1165 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1169 /* linker_addinterface *********************************************************
1171 Is needed by link_class for adding a VTBL to a class. All
1172 interfaces implemented by ic are added as well.
1175 true.........everything ok
1176 false........an exception has been thrown
1178 *******************************************************************************/
1180 static bool linker_addinterface(classinfo *c, classinfo *ic)
1191 if (i >= v->interfacetablelength)
1192 vm_abort("Internal error: interfacetable overflow");
1194 /* if this interface has already been added, return immediately */
1196 if (v->interfacetable[-i] != NULL)
1199 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1200 v->interfacevftbllength[i] = 1;
1201 v->interfacetable[-i] = MNEW(methodptr, 1);
1202 v->interfacetable[-i][0] = NULL;
1205 v->interfacevftbllength[i] = ic->methodscount;
1206 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1208 #if defined(ENABLE_STATISTICS)
1210 count_vftbl_len += sizeof(methodptr) *
1211 (ic->methodscount + (ic->methodscount == 0));
1214 for (j = 0; j < ic->methodscount; j++) {
1215 for (sc = c; sc != NULL; sc = sc->super) {
1216 for (k = 0; k < sc->methodscount; k++) {
1217 m = &(sc->methods[k]);
1219 if (method_canoverwrite(m, &(ic->methods[j]))) {
1220 /* method m overwrites the (abstract) method */
1221 #if defined(ENABLE_VERIFIER)
1222 /* Add loading constraints (for the more
1223 general types of the method
1225 if (!classcache_add_constraints_for_params(
1226 c->classloader, ic->classloader,
1233 /* XXX taken from gcj */
1234 /* check for ACC_STATIC: IncompatibleClassChangeError */
1236 /* check for !ACC_PUBLIC: IllegalAccessError */
1238 /* check for ACC_ABSTRACT: AbstracMethodError,
1239 not sure about that one */
1241 v->interfacetable[-i][j] = v->table[m->vftblindex];
1247 /* If no method was found, insert the AbstractMethodError
1250 #if defined(ENABLE_JIT)
1251 # if defined(ENABLE_INTRP)
1253 v->interfacetable[-i][j] =
1254 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1257 v->interfacetable[-i][j] =
1258 (methodptr) (ptrint) &asm_abstractmethoderror;
1260 v->interfacetable[-i][j] =
1261 (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1269 /* add superinterfaces of this interface */
1271 for (j = 0; j < ic->interfacescount; j++)
1272 if (!linker_addinterface(c, ic->interfaces[j]))
1281 /* class_highestinterface ******************************************************
1283 Used by the function link_class to determine the amount of memory
1284 needed for the interface table.
1286 *******************************************************************************/
1288 static s4 class_highestinterface(classinfo *c)
1294 /* check for ACC_INTERFACE bit already done in link_class_intern */
1298 for (i = 0; i < c->interfacescount; i++) {
1299 h2 = class_highestinterface(c->interfaces[i]);
1310 * These are local overrides for various environment variables in Emacs.
1311 * Please do not remove this and leave it at the end of the file, where
1312 * Emacs will automagically detect them.
1313 * ---------------------------------------------------------------------
1316 * indent-tabs-mode: t
1320 * vim:noexpandtab:sw=4:ts=4: