Line data Source code
1 : /* src/vm/linker.cpp - class linker functions
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
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.
12 :
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.
17 :
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
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "vm/linker.hpp"
27 : #include "config.h"
28 :
29 : #include <cassert>
30 : #include <vector>
31 : #include <utility>
32 :
33 : #include "mm/memory.hpp"
34 :
35 : #include "native/native.hpp"
36 :
37 : #include "threads/lock.hpp"
38 : #include "threads/mutex.hpp"
39 :
40 : #include "toolbox/logging.hpp"
41 :
42 : #include "vm/access.hpp"
43 : #include "vm/array.hpp"
44 : #include "vm/class.hpp"
45 : #include "vm/classcache.hpp"
46 : #include "vm/descriptor.hpp"
47 : #include "vm/exceptions.hpp"
48 : #include "vm/field.hpp"
49 : #include "vm/globals.hpp"
50 : #include "vm/hook.hpp"
51 : #include "vm/loader.hpp"
52 : #include "vm/options.hpp"
53 : #include "vm/primitive.hpp"
54 : #include "vm/rt-timing.hpp"
55 : #include "vm/string.hpp"
56 : #include "vm/types.hpp"
57 : #include "vm/vm.hpp"
58 :
59 : #include "vm/jit/asmpart.hpp"
60 : #include "vm/jit/jit.hpp"
61 : #include "vm/jit/stubs.hpp"
62 :
63 : using namespace cacao;
64 :
65 :
66 : STAT_DECLARE_VAR(int,count_vftbl_len,0)
67 :
68 :
69 : /* debugging macros ***********************************************************/
70 :
71 : #if !defined(NDEBUG)
72 : # define TRACELINKCLASS(c) \
73 : do { \
74 : if (opt_TraceLinkClass) { \
75 : log_start(); \
76 : log_print("[Linking "); \
77 : class_print((c)); \
78 : log_print("]"); \
79 : log_finish(); \
80 : } \
81 : } while (0)
82 : #else
83 : # define TRACELINKCLASS(c)
84 : #endif
85 :
86 :
87 : /* #include "vm/resolve.hpp" */
88 : /* copied prototype to avoid bootstrapping problem: */
89 : classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
90 :
91 : #include "vm/statistics.hpp"
92 :
93 : #if !defined(NDEBUG) && defined(ENABLE_INLINING)
94 : #define INLINELOG(code) do { if (opt_TraceInlining) { code } } while (0)
95 : #else
96 : #define INLINELOG(code)
97 : #endif
98 :
99 :
100 : /* global variables ***********************************************************/
101 :
102 : static s4 interfaceindex; /* sequential numbering of interfaces */
103 : static s4 classvalue;
104 :
105 : #if !USES_NEW_SUBTYPE
106 : Mutex *linker_classrenumber_lock;
107 : #endif
108 :
109 : /* private functions **********************************************************/
110 :
111 : static classinfo *link_class_intern(classinfo *c);
112 : static arraydescriptor *link_array(classinfo *c);
113 : #if !USES_NEW_SUBTYPE
114 : static void linker_compute_class_values(classinfo *c);
115 : #endif
116 : static void linker_compute_subclasses(classinfo *c);
117 : static bool linker_addinterface(classinfo *c, classinfo *ic);
118 : static s4 class_highestinterface(classinfo *c);
119 :
120 :
121 : typedef std::vector<std::pair<java_object_t**, Utf8String> > deferred_strings_vec_t;
122 165 : static deferred_strings_vec_t deferred_strings;
123 :
124 : /* linker_init *****************************************************************
125 :
126 : Initializes the linker subsystem and links classes required for the
127 : primitive table.
128 :
129 : *******************************************************************************/
130 :
131 163 : void linker_preinit(void)
132 : {
133 163 : TRACESUBSYSTEMINITIALIZATION("linker_preinit");
134 :
135 : /* Reset interface index. */
136 :
137 163 : interfaceindex = 0;
138 :
139 : #if !USES_NEW_SUBTYPE
140 : /* create the global mutex */
141 :
142 : linker_classrenumber_lock = new Mutex();
143 : #endif
144 :
145 : /* Link the most basic classes. */
146 :
147 163 : if (!link_class(class_java_lang_Object))
148 0 : vm_abort("linker_preinit: linking java/lang/Object failed");
149 :
150 : #if defined(ENABLE_JAVASE)
151 163 : if (!link_class(class_java_lang_Cloneable))
152 0 : vm_abort("linker_preinit: linking java/lang/Cloneable failed");
153 :
154 163 : if (!link_class(class_java_io_Serializable))
155 0 : vm_abort("linker_preinit: linking java/io/Serializable failed");
156 : #endif
157 163 : }
158 :
159 :
160 : /* linker_init *****************************************************************
161 :
162 : Links all classes required in the VM.
163 :
164 : *******************************************************************************/
165 :
166 163 : void linker_init(void)
167 : {
168 163 : TRACESUBSYSTEMINITIALIZATION("linker_init");
169 :
170 : /* Link java.lang.Class as first class of the system, because we
171 : need it's vftbl for all other classes so we can use a class as
172 : object. */
173 :
174 163 : if (!link_class(class_java_lang_Class))
175 0 : vm_abort("linker_init: linking java/lang/Class failed");
176 :
177 : /* Now set the header.vftbl of all classes which were created
178 : before java.lang.Class was linked. */
179 :
180 163 : class_postset_header_vftbl();
181 :
182 : /* Link primitive-type wrapping classes. */
183 :
184 : #if defined(ENABLE_JAVASE)
185 163 : if (!link_class(class_java_lang_Void))
186 0 : vm_abort("linker_init: linking failed");
187 : #endif
188 :
189 163 : if (!link_class(class_java_lang_Boolean))
190 0 : vm_abort("linker_init: linking failed");
191 :
192 163 : if (!link_class(class_java_lang_Byte))
193 0 : vm_abort("linker_init: linking failed");
194 :
195 163 : if (!link_class(class_java_lang_Character))
196 0 : vm_abort("linker_init: linking failed");
197 :
198 163 : if (!link_class(class_java_lang_Short))
199 0 : vm_abort("linker_init: linking failed");
200 :
201 163 : if (!link_class(class_java_lang_Integer))
202 0 : vm_abort("linker_init: linking failed");
203 :
204 163 : if (!link_class(class_java_lang_Long))
205 0 : vm_abort("linker_init: linking failed");
206 :
207 163 : if (!link_class(class_java_lang_Float))
208 0 : vm_abort("linker_init: linking failed");
209 :
210 163 : if (!link_class(class_java_lang_Double))
211 0 : vm_abort("linker_init: linking failed");
212 :
213 : /* Link important system classes. */
214 :
215 163 : if (!link_class(class_java_lang_String))
216 0 : vm_abort("linker_init: linking java/lang/String failed");
217 :
218 : #if defined(ENABLE_JAVASE)
219 163 : if (!link_class(class_java_lang_ClassLoader))
220 0 : vm_abort("linker_init: linking failed");
221 :
222 163 : if (!link_class(class_java_lang_SecurityManager))
223 0 : vm_abort("linker_init: linking failed");
224 : #endif
225 :
226 163 : if (!link_class(class_java_lang_System))
227 0 : vm_abort("linker_init: linking failed");
228 :
229 163 : if (!link_class(class_java_lang_Thread))
230 0 : vm_abort("linker_init: linking failed");
231 :
232 : #if defined(ENABLE_JAVASE)
233 163 : if (!link_class(class_java_lang_ThreadGroup))
234 0 : vm_abort("linker_init: linking failed");
235 : #endif
236 :
237 163 : if (!link_class(class_java_lang_Throwable))
238 0 : vm_abort("linker_init: linking failed");
239 :
240 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
241 163 : if (!link_class(class_java_lang_VMSystem))
242 0 : vm_abort("linker_init: linking failed");
243 :
244 163 : if (!link_class(class_java_lang_VMThread))
245 0 : vm_abort("linker_init: linking failed");
246 :
247 163 : if (!link_class(class_java_lang_VMThrowable))
248 0 : vm_abort("linker_init: linking failed");
249 : #endif
250 :
251 : /* Important system exceptions. */
252 :
253 163 : if (!link_class(class_java_lang_Exception))
254 0 : vm_abort("linker_init: linking failed");
255 :
256 163 : if (!link_class(class_java_lang_ClassNotFoundException))
257 0 : vm_abort("linker_init: linking failed");
258 :
259 163 : if (!link_class(class_java_lang_RuntimeException))
260 0 : vm_abort("linker_init: linking failed");
261 :
262 : /* some classes which may be used more often */
263 :
264 : #if defined(ENABLE_JAVASE)
265 163 : if (!link_class(class_java_lang_StackTraceElement))
266 0 : vm_abort("linker_init: linking failed");
267 :
268 163 : if (!link_class(class_java_lang_reflect_Constructor))
269 0 : vm_abort("linker_init: linking failed");
270 :
271 163 : if (!link_class(class_java_lang_reflect_Field))
272 0 : vm_abort("linker_init: linking failed");
273 :
274 163 : if (!link_class(class_java_lang_reflect_Method))
275 0 : vm_abort("linker_init: linking failed");
276 :
277 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
278 163 : if (!link_class(class_java_lang_reflect_VMConstructor))
279 0 : vm_abort("linker_init: linking failed");
280 :
281 163 : if (!link_class(class_java_lang_reflect_VMField))
282 0 : vm_abort("linker_init: linking failed");
283 :
284 163 : if (!link_class(class_java_lang_reflect_VMMethod))
285 0 : vm_abort("linker_init: linking failed");
286 : # endif
287 :
288 163 : if (!link_class(class_java_security_PrivilegedAction))
289 0 : vm_abort("linker_init: linking failed");
290 :
291 163 : if (!link_class(class_java_util_Vector))
292 0 : vm_abort("linker_init: linking failed");
293 :
294 163 : if (!link_class(class_java_util_HashMap))
295 0 : vm_abort("linker_init: linking failed");
296 :
297 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
298 : if (!link_class(class_sun_misc_Signal))
299 : vm_abort("linker_init: linking failed");
300 :
301 : if (!link_class(class_sun_reflect_MagicAccessorImpl))
302 : vm_abort("linker_init: linking failed");
303 :
304 : if (!link_class(class_sun_reflect_MethodAccessorImpl))
305 : vm_abort("linker_init: linking failed");
306 :
307 : if (!link_class(class_sun_reflect_ConstructorAccessorImpl))
308 : vm_abort("linker_init: linking failed");
309 : # endif
310 :
311 163 : if (!link_class(arrayclass_java_lang_Object))
312 0 : vm_abort("linker_init: linking failed");
313 : #endif
314 :
315 :
316 : /* create pseudo classes used by the typechecker */
317 :
318 : /* pseudo class for Arraystubs (extends java.lang.Object) */
319 :
320 : pseudo_class_Arraystub =
321 163 : class_create_classinfo(Utf8String::from_utf8("$ARRAYSTUB$"));
322 163 : pseudo_class_Arraystub->state |= CLASS_LOADED;
323 163 : pseudo_class_Arraystub->super = class_java_lang_Object;
324 :
325 : #if defined(ENABLE_JAVASE)
326 :
327 163 : pseudo_class_Arraystub->interfacescount = 2;
328 163 : pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
329 163 : pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
330 163 : pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
331 :
332 : #elif defined(ENABLE_JAVAME_CLDC1_1)
333 :
334 : pseudo_class_Arraystub->interfacescount = 0;
335 : pseudo_class_Arraystub->interfaces = NULL;
336 :
337 : #else
338 : # error unknown Java configuration
339 : #endif
340 :
341 163 : if (!classcache_store_unique(pseudo_class_Arraystub))
342 0 : vm_abort("linker_init: could not cache pseudo_class_Arraystub");
343 :
344 163 : if (!link_class(pseudo_class_Arraystub))
345 0 : vm_abort("linker_init: linking pseudo_class_Arraystub failed");
346 :
347 : /* pseudo class representing the null type */
348 :
349 163 : pseudo_class_Null = class_create_classinfo(Utf8String::from_utf8("$NULL$"));
350 163 : pseudo_class_Null->state |= CLASS_LOADED;
351 163 : pseudo_class_Null->super = class_java_lang_Object;
352 :
353 163 : if (!classcache_store_unique(pseudo_class_Null))
354 0 : vm_abort("linker_init: could not cache pseudo_class_Null");
355 :
356 163 : if (!link_class(pseudo_class_Null))
357 0 : vm_abort("linker_init: linking failed");
358 :
359 : /* pseudo class representing new uninitialized objects */
360 :
361 163 : pseudo_class_New = class_create_classinfo(Utf8String::from_utf8("$NEW$"));
362 163 : pseudo_class_New->state |= CLASS_LOADED;
363 163 : pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
364 163 : pseudo_class_New->super = class_java_lang_Object;
365 :
366 163 : if (!classcache_store_unique(pseudo_class_New))
367 0 : vm_abort("linker_init: could not cache pseudo_class_New");
368 163 : }
369 :
370 :
371 : /* link_class ******************************************************************
372 :
373 : Wrapper function for link_class_intern to ease monitor enter/exit
374 : and exception handling.
375 :
376 : *******************************************************************************/
377 :
378 86480 : classinfo *link_class(classinfo *c)
379 : {
380 : classinfo *r;
381 :
382 86480 : if (c == NULL) {
383 0 : exceptions_throw_nullpointerexception();
384 0 : return 0;
385 : }
386 :
387 86480 : LOCK_MONITOR_ENTER(c);
388 :
389 : /* Maybe the class is currently linking or is already linked.*/
390 :
391 86480 : if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
392 44278 : LOCK_MONITOR_EXIT(c);
393 :
394 44278 : return c;
395 : }
396 :
397 : #if defined(ENABLE_STATISTICS)
398 : /* measure time */
399 :
400 : if (opt_getcompilingtime)
401 : compilingtime_stop();
402 :
403 : if (opt_getloadingtime)
404 : loadingtime_start();
405 : #endif
406 :
407 : /* call the internal function */
408 :
409 42202 : r = link_class_intern(c);
410 :
411 : /* If return value is NULL, we had a problem and the class is not
412 : linked. */
413 :
414 42202 : if (r == NULL)
415 1 : c->state &= ~CLASS_LINKING;
416 :
417 : #if defined(ENABLE_STATISTICS)
418 : /* measure time */
419 :
420 : if (opt_getloadingtime)
421 : loadingtime_stop();
422 :
423 : if (opt_getcompilingtime)
424 : compilingtime_start();
425 : #endif
426 :
427 42202 : LOCK_MONITOR_EXIT(c);
428 :
429 :
430 : // Hook point just after a class was linked.
431 42202 : if (!Hook::class_linked(r))
432 0 : return 0;
433 :
434 42202 : return r;
435 : }
436 :
437 :
438 : /* linker_overwrite_method *****************************************************
439 :
440 : Overwrite a method with another one, update method flags and check
441 : assumptions.
442 :
443 : IN:
444 : mg................the general method being overwritten
445 : ms................the overwriting (more specialized) method
446 : wl................worklist where to add invalidated methods
447 :
448 : RETURN VALUE:
449 : true..............everything ok
450 : false.............an exception has been thrown
451 :
452 : *******************************************************************************/
453 :
454 117343 : static bool linker_overwrite_method(methodinfo *mg,
455 : methodinfo *ms,
456 : method_worklist **wl)
457 : {
458 : /* overriding a final method is illegal */
459 :
460 117343 : if (mg->flags & ACC_FINAL) {
461 0 : exceptions_throw_verifyerror(mg, "Overriding final method");
462 0 : return false;
463 : }
464 :
465 : /* method ms overwrites method mg */
466 :
467 : #if defined(ENABLE_VERIFIER)
468 : /* Add loading constraints (for the more general types of method mg). */
469 : /* Not for <init>, as it is not invoked virtually. */
470 :
471 117343 : if ((ms->name != utf8::init)
472 : && !classcache_add_constraints_for_params(
473 : ms->clazz->classloader, mg->clazz->classloader, mg))
474 : {
475 0 : return false;
476 : }
477 : #endif
478 :
479 : /* inherit the vftbl index, and record the overwriting */
480 :
481 117343 : ms->vftblindex = mg->vftblindex;
482 117343 : ms->overwrites = mg;
483 :
484 : /* update flags and check assumptions */
485 : /* <init> methods are a special case, as they are never dispatched dynamically */
486 :
487 117343 : if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf8::init) {
488 94571 : do {
489 :
490 : #if defined(ENABLE_TLH)
491 : if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
492 : printf("%s/%s is evil! the sinner is %s/%s\n",
493 : mg->clazz->name.begin(),
494 : mg->name.begin(),
495 : ms->clazz->name.begin(),
496 : ms->name.begin());
497 : ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;
498 : }
499 : #endif
500 :
501 94571 : if (mg->flags & ACC_METHOD_IMPLEMENTED) {
502 : /* this adds another implementation */
503 :
504 76646 : mg->flags &= ~ACC_METHOD_MONOMORPHIC;
505 :
506 : INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
507 :
508 76646 : method_break_assumption_monomorphic(mg, wl);
509 : }
510 : else {
511 : /* this is the first implementation */
512 :
513 17925 : mg->flags |= ACC_METHOD_IMPLEMENTED;
514 :
515 : INLINELOG( printf("becomes implemented: "); method_println(mg); );
516 : }
517 :
518 94571 : ms = mg;
519 94571 : mg = mg->overwrites;
520 : } while (mg != NULL);
521 : }
522 :
523 117343 : return true;
524 : }
525 :
526 :
527 : #if USES_NEW_SUBTYPE
528 : /* build_display ***************************************************************
529 :
530 : Builds the entire display for a class. This entails filling the fixed part
531 : as well as allocating and initializing the overflow part.
532 :
533 : See Cliff Click and John Rose: Fast subtype checking in the Hotspot JVM.
534 :
535 : *******************************************************************************/
536 :
537 42201 : static classinfo *build_display(classinfo *c)
538 : {
539 : int depth, i;
540 : int depth_fixed;
541 : classinfo *super;
542 :
543 : do {
544 : /* Handle arrays. */
545 42201 : if (c->vftbl->arraydesc) {
546 4943 : arraydescriptor *a = c->vftbl->arraydesc;
547 4943 : if (a->elementvftbl && a->elementvftbl->clazz->super) {
548 2922 : classinfo *cls = a->elementvftbl->clazz->super;
549 : int n;
550 5865 : for (n=0; n<a->dimension; n++)
551 2943 : cls = class_array_of(cls, true);
552 2922 : super = cls;
553 2922 : break;
554 : }
555 2021 : if (a->componentvftbl && a->elementvftbl) {
556 170 : super = a->componentvftbl->clazz;
557 170 : break;
558 : }
559 : }
560 : /* Normal classes. */
561 39109 : super = c->super;
562 : } while (false);
563 42201 : if (super) {
564 40571 : if (!link_class(super))
565 0 : return NULL;
566 40571 : depth = super->vftbl->subtype_depth + 1;
567 : } else
568 : /* java.lang.Object doesn't have a super class. */
569 1630 : depth = 0;
570 :
571 : /* Now copy super's display, append c->vftbl and initialize the remaining fields. */
572 42201 : if (depth >= DISPLAY_SIZE) {
573 915 : c->vftbl->subtype_overflow = MNEW(vftbl_t *, depth - DISPLAY_SIZE + 1);
574 : STATISTICS(count_vftbl_len += sizeof(vftbl_t*) * (depth - DISPLAY_SIZE + 1));
575 915 : memcpy(c->vftbl->subtype_overflow, super->vftbl->subtype_overflow, sizeof(vftbl_t*) * (depth - DISPLAY_SIZE));
576 915 : c->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
577 915 : depth_fixed = DISPLAY_SIZE;
578 : }
579 : else {
580 41286 : depth_fixed = depth;
581 41286 : c->vftbl->subtype_display[depth] = c->vftbl;
582 : }
583 :
584 42201 : if (super)
585 40571 : memcpy(c->vftbl->subtype_display, super->vftbl->subtype_display, sizeof(vftbl_t*) * depth_fixed);
586 145004 : for (i=depth_fixed+1; i<=DISPLAY_SIZE; i++)
587 102803 : c->vftbl->subtype_display[i] = NULL;
588 42201 : c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(vftbl_t*) * depth_fixed;
589 42201 : c->vftbl->subtype_depth = depth;
590 :
591 42201 : return c;
592 : }
593 : #endif
594 :
595 : // register linker real-time group
596 : RT_REGISTER_GROUP(linker_group,"link","linker")
597 :
598 : // register real-time timers
599 : RT_REGISTER_GROUP_TIMER(resolving_timer, "link", "resolve superclass/superinterfaces",linker_group)
600 : RT_REGISTER_GROUP_TIMER(compute_vftbl_timer, "link", "compute vftbl length",linker_group)
601 : RT_REGISTER_GROUP_TIMER(abstract_timer, "link", "handle abstract methods",linker_group)
602 : RT_REGISTER_GROUP_TIMER(compute_iftbl_timer, "link", "compute interface table",linker_group)
603 : RT_REGISTER_GROUP_TIMER(fill_vftbl_timer, "link", "fill vftbl",linker_group)
604 : RT_REGISTER_GROUP_TIMER(offsets_timer, "link", "set offsets",linker_group)
605 : RT_REGISTER_GROUP_TIMER(fill_iftbl_timer, "link", "fill interface table",linker_group)
606 : RT_REGISTER_GROUP_TIMER(finalizer_timer, "link", "set finalizer",linker_group)
607 : //RT_REGISTER_GROUP_TIMER(checks_timer, "link", "resolve exception classes",linker_group)
608 : RT_REGISTER_GROUP_TIMER(subclasses_timer, "link", "re-calculate subclass indices",linker_group)
609 :
610 : /* link_class_intern ***********************************************************
611 :
612 : Tries to link a class. The function calculates the length in bytes
613 : that an instance of this class requires as well as the VTBL for
614 : methods and interface methods.
615 :
616 : *******************************************************************************/
617 :
618 42202 : static classinfo *link_class_intern(classinfo *c)
619 : {
620 : classinfo *super; /* super class */
621 : classinfo *tc; /* temporary class variable */
622 : s4 supervftbllength; /* vftbllegnth of super class */
623 : s4 vftbllength; /* vftbllength of current class */
624 : s4 interfacetablelength; /* interface table length */
625 : vftbl_t *v; /* vftbl of current class */
626 : s4 i; /* interface/method/field counter */
627 : arraydescriptor *arraydesc; /* descriptor for array classes */
628 : method_worklist *worklist; /* worklist for recompilation */
629 :
630 : RT_TIMER_START(resolving_timer);
631 :
632 42202 : TRACELINKCLASS(c);
633 :
634 : /* the class must be loaded */
635 :
636 : /* XXX should this be a specific exception? */
637 42202 : assert(c->state & CLASS_LOADED);
638 :
639 : /* This is check in link_class. */
640 :
641 42202 : assert(!(c->state & CLASS_LINKED));
642 :
643 : /* cache the self-reference of this class */
644 : /* we do this for cases where the defining loader of the class */
645 : /* has not yet been recorded as an initiating loader for the class */
646 : /* this is needed so subsequent code can assume that self-refs */
647 : /* will always resolve lazily */
648 : /* No need to do it for the bootloader - it is always registered */
649 : /* as initiating loader for the classes it loads. */
650 42202 : if (c->classloader)
651 651 : classcache_store(c->classloader,c,false);
652 :
653 : /* this class is currently linking */
654 :
655 42202 : c->state |= CLASS_LINKING;
656 :
657 42202 : arraydesc = NULL;
658 42202 : worklist = NULL;
659 :
660 : /* Link the super interfaces. */
661 :
662 72854 : for (i = 0; i < c->interfacescount; i++) {
663 30652 : tc = c->interfaces[i];
664 :
665 30652 : if (!(tc->state & CLASS_LINKED))
666 5033 : if (!link_class(tc))
667 0 : return NULL;
668 : }
669 :
670 : /* check super class */
671 :
672 42202 : super = NULL;
673 :
674 : /* Check for java/lang/Object. */
675 :
676 42202 : if (c->super == NULL) {
677 1630 : c->index = 0;
678 1630 : c->instancesize = sizeof(java_object_t);
679 :
680 1630 : vftbllength = supervftbllength = 0;
681 :
682 1630 : c->finalizer = NULL;
683 : }
684 : else {
685 : /* Get super class. */
686 :
687 40572 : super = c->super;
688 :
689 : /* Link the super class if necessary. */
690 :
691 40572 : if (!(super->state & CLASS_LINKED))
692 5666 : if (!link_class(super))
693 0 : return NULL;
694 :
695 : /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
696 : flags. */
697 :
698 : c->flags |= (super->flags &
699 40572 : (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
700 :
701 : /* handle array classes */
702 :
703 40572 : if (c->name[0] == '[')
704 4944 : if (!(arraydesc = link_array(c)))
705 1 : return NULL;
706 :
707 40571 : if (c->flags & ACC_INTERFACE)
708 6012 : c->index = interfaceindex++;
709 : else
710 34559 : c->index = super->index + 1;
711 :
712 40571 : c->instancesize = super->instancesize;
713 :
714 40571 : vftbllength = supervftbllength = super->vftbl->vftbllength;
715 :
716 40571 : c->finalizer = super->finalizer;
717 : }
718 : RT_TIMER_STOPSTART(resolving_timer,compute_vftbl_timer);
719 :
720 :
721 : /* compute vftbl length */
722 :
723 506821 : for (i = 0; i < c->methodscount; i++) {
724 464620 : methodinfo *m = &(c->methods[i]);
725 :
726 464620 : if (!(m->flags & ACC_STATIC)) { /* is instance method */
727 361696 : tc = super;
728 :
729 1094320 : while (tc) {
730 : s4 j;
731 :
732 6584051 : for (j = 0; j < tc->methodscount; j++) {
733 6213123 : if (method_canoverwrite(m, &(tc->methods[j]))) {
734 117343 : if (tc->methods[j].flags & ACC_PRIVATE)
735 0 : goto notfoundvftblindex;
736 :
737 : /* package-private methods in other packages */
738 : /* must not be overridden */
739 : /* (see Java Language Specification 8.4.8.1) */
740 117343 : if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
741 : && !SAME_PACKAGE(c,tc) )
742 : {
743 0 : goto notfoundvftblindex;
744 : }
745 :
746 117343 : if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
747 0 : return NULL;
748 :
749 117343 : goto foundvftblindex;
750 : }
751 : }
752 :
753 370928 : tc = tc->super;
754 : }
755 :
756 : notfoundvftblindex:
757 244353 : m->vftblindex = (vftbllength++);
758 : foundvftblindex:
759 : ;
760 : }
761 : }
762 : RT_TIMER_STOPSTART(compute_vftbl_timer,abstract_timer);
763 :
764 :
765 : /* Check all interfaces of an abstract class (maybe be an
766 : interface too) for unimplemented methods. Such methods are
767 : called miranda-methods and are marked with the ACC_MIRANDA
768 : flag. VMClass.getDeclaredMethods does not return such
769 : methods. */
770 :
771 42201 : if (c->flags & ACC_ABSTRACT) {
772 : classinfo *ic;
773 : methodinfo *im;
774 : s4 abstractmethodscount;
775 : s4 j;
776 : s4 k;
777 :
778 17253 : abstractmethodscount = 0;
779 :
780 : /* check all interfaces of the abstract class */
781 :
782 33105 : for (i = 0; i < c->interfacescount; i++) {
783 15852 : ic = c->interfaces[i];
784 :
785 45018 : for (j = 0; j < ic->methodscount; j++) {
786 29166 : im = &(ic->methods[j]);
787 :
788 : /* skip `<clinit>' and `<init>' */
789 :
790 29166 : if ((im->name == utf8::clinit) || (im->name == utf8::init))
791 0 : continue;
792 :
793 45284 : for (tc = c; tc != NULL; tc = tc->super) {
794 479566 : for (k = 0; k < tc->methodscount; k++) {
795 463448 : if (method_canoverwrite(im, &(tc->methods[k])))
796 23619 : goto noabstractmethod;
797 : }
798 : }
799 :
800 5547 : abstractmethodscount++;
801 :
802 : noabstractmethod:
803 : ;
804 : }
805 : }
806 :
807 17253 : if (abstractmethodscount > 0) {
808 : methodinfo *am;
809 :
810 : /* reallocate methods memory */
811 :
812 : c->methods = (methodinfo*) MREALLOC(c->methods, methodinfo, c->methodscount,
813 1305 : c->methodscount + abstractmethodscount);
814 :
815 3033 : for (i = 0; i < c->interfacescount; i++) {
816 1728 : ic = c->interfaces[i];
817 :
818 10061 : for (j = 0; j < ic->methodscount; j++) {
819 8333 : im = &(ic->methods[j]);
820 :
821 : /* skip `<clinit>' and `<init>' */
822 :
823 8333 : if ((im->name == utf8::clinit) || (im->name == utf8::init))
824 0 : continue;
825 :
826 19393 : for (tc = c; tc != NULL; tc = tc->super) {
827 212780 : for (k = 0; k < tc->methodscount; k++) {
828 201720 : if (method_canoverwrite(im, &(tc->methods[k])))
829 3068 : goto noabstractmethod2;
830 : }
831 : }
832 :
833 : /* Copy the method found into the new c->methods
834 : array and tag it as miranda-method. */
835 :
836 5265 : am = &(c->methods[c->methodscount]);
837 5265 : c->methodscount++;
838 :
839 5265 : MCOPY(am, im, methodinfo, 1);
840 :
841 5265 : am->vftblindex = (vftbllength++);
842 5265 : am->clazz = c;
843 5265 : am->flags |= ACC_MIRANDA;
844 :
845 : noabstractmethod2:
846 : ;
847 : }
848 : }
849 : }
850 : }
851 : RT_TIMER_STOPSTART(abstract_timer,compute_iftbl_timer);
852 :
853 :
854 : STATISTICS(count_vftbl_len +=
855 : sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1)));
856 :
857 : /* compute interfacetable length */
858 :
859 42201 : interfacetablelength = 0;
860 :
861 146341 : for (tc = c; tc != NULL; tc = tc->super) {
862 152429 : for (i = 0; i < tc->interfacescount; i++) {
863 48289 : s4 h = class_highestinterface(tc->interfaces[i]) + 1;
864 :
865 48289 : if (h > interfacetablelength)
866 36411 : interfacetablelength = h;
867 : }
868 : }
869 : RT_TIMER_STOPSTART(compute_iftbl_timer,fill_vftbl_timer);
870 :
871 : /* allocate virtual function table */
872 :
873 : v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
874 : sizeof(methodptr) * (vftbllength - 1) +
875 42201 : sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
876 : v = (vftbl_t *) (((methodptr *) v) +
877 42201 : (interfacetablelength - 1) * (interfacetablelength > 1));
878 :
879 42201 : c->vftbl = v;
880 42201 : v->clazz = c;
881 42201 : v->vftbllength = vftbllength;
882 42201 : v->interfacetablelength = interfacetablelength;
883 42201 : v->arraydesc = arraydesc;
884 :
885 : /* store interface index in vftbl */
886 :
887 42201 : if (c->flags & ACC_INTERFACE)
888 6012 : v->baseval = -(c->index);
889 :
890 : /* copy virtual function table of super class */
891 :
892 757302 : for (i = 0; i < supervftbllength; i++)
893 715101 : v->table[i] = super->vftbl->table[i];
894 :
895 : /* Fill the remaining vftbl slots with the AbstractMethodError
896 : stub (all after the super class slots, because they are already
897 : initialized). */
898 :
899 291819 : for (; i < vftbllength; i++) {
900 : #if defined(ENABLE_JIT)
901 : # if defined(ENABLE_INTRP)
902 : if (opt_intrp)
903 : v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
904 : else
905 : # endif
906 249618 : v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
907 : #else
908 : v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
909 : #endif
910 : }
911 :
912 : /* add method stubs into virtual function table */
913 :
914 512086 : for (i = 0; i < c->methodscount; i++) {
915 469885 : methodinfo *m = &(c->methods[i]);
916 :
917 469885 : assert(m->stubroutine == NULL);
918 :
919 : /* Don't create a compiler stub for abstract methods as they
920 : throw an AbstractMethodError with the default stub in the
921 : vftbl. This entry is simply copied by sub-classes. */
922 :
923 469885 : if (m->flags & ACC_ABSTRACT)
924 47163 : continue;
925 :
926 : #if defined(ENABLE_JIT)
927 : # if defined(ENABLE_INTRP)
928 : if (opt_intrp)
929 : m->stubroutine = intrp_createcompilerstub(m);
930 : else
931 : #endif
932 422722 : m->stubroutine = (u1*) CompilerStub::generate(m);
933 : #else
934 : m->stubroutine = intrp_createcompilerstub(m);
935 : #endif
936 :
937 : /* static methods are not in the vftbl */
938 :
939 422722 : if (m->flags & ACC_STATIC)
940 102924 : continue;
941 :
942 : /* insert the stubroutine into the vftbl */
943 :
944 319798 : v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
945 : }
946 : RT_TIMER_STOPSTART(fill_vftbl_timer,offsets_timer);
947 :
948 : /* compute instance size and offset of each field */
949 :
950 155087 : for (i = 0; i < c->fieldscount; i++) {
951 : s4 dsize;
952 112886 : fieldinfo *f = &(c->fields[i]);
953 :
954 112886 : if (!(f->flags & ACC_STATIC)) {
955 52174 : dsize = f->parseddesc->typesize();
956 52174 : c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
957 52174 : f->offset = c->instancesize;
958 52174 : c->instancesize += dsize;
959 : }
960 : }
961 : RT_TIMER_STOPSTART(offsets_timer,fill_iftbl_timer);
962 :
963 : /* initialize interfacetable and interfacevftbllength */
964 :
965 42201 : v->interfacevftbllength = MNEW(s4, interfacetablelength);
966 :
967 : STATISTICS(count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength);
968 :
969 326557 : for (i = 0; i < interfacetablelength; i++) {
970 284356 : v->interfacevftbllength[i] = 0;
971 284356 : v->interfacetable[-i] = NULL;
972 : }
973 :
974 : /* add interfaces */
975 :
976 146341 : for (tc = c; tc != NULL; tc = tc->super)
977 152429 : for (i = 0; i < tc->interfacescount; i++)
978 48289 : if (!linker_addinterface(c, tc->interfaces[i]))
979 0 : return NULL;
980 :
981 : RT_TIMER_STOPSTART(fill_iftbl_timer,finalizer_timer);
982 :
983 : /* add finalizer method (not for java.lang.Object) */
984 :
985 42201 : if (super) {
986 : methodinfo *fi;
987 :
988 40571 : fi = class_findmethod(c, utf8::finalize, utf8::void__void);
989 :
990 40571 : if (fi)
991 752 : if (!(fi->flags & ACC_STATIC))
992 752 : c->finalizer = fi;
993 : }
994 : RT_TIMER_STOPSTART(finalizer_timer,subclasses_timer);
995 :
996 : /* final tasks */
997 :
998 42201 : linker_compute_subclasses(c);
999 :
1000 : /* FIXME: this is completely useless now */
1001 : RT_TIMER_STOP(subclasses_timer);
1002 :
1003 : #if USES_NEW_SUBTYPE
1004 42201 : if (!build_display(c))
1005 0 : return NULL;
1006 : #endif
1007 :
1008 : /* revert the linking state and class is linked */
1009 :
1010 42201 : c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
1011 :
1012 : /* check worklist */
1013 :
1014 : /* XXX must this also be done in case of exception? */
1015 :
1016 84402 : while (worklist != NULL) {
1017 0 : method_worklist *wi = worklist;
1018 :
1019 0 : worklist = worklist->next;
1020 :
1021 : INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
1022 0 : jit_invalidate_code(wi->m);
1023 :
1024 : /* XXX put worklist into dump memory? */
1025 0 : FREE(wi, method_worklist);
1026 : }
1027 :
1028 : /* just return c to show that we didn't had a problem */
1029 :
1030 42201 : return c;
1031 : }
1032 :
1033 :
1034 : /* link_array ******************************************************************
1035 :
1036 : This function is called by link_class to create the arraydescriptor
1037 : for an array class.
1038 :
1039 : This function returns NULL if the array cannot be linked because
1040 : the component type has not been linked yet.
1041 :
1042 : *******************************************************************************/
1043 :
1044 4944 : static arraydescriptor *link_array(classinfo *c)
1045 : {
1046 : classinfo *comp;
1047 : s4 namelen;
1048 : arraydescriptor *desc;
1049 : vftbl_t *compvftbl;
1050 4944 : Utf8String u;
1051 :
1052 4944 : comp = NULL;
1053 4944 : namelen = c->name.size();
1054 :
1055 : /* Check the component type */
1056 :
1057 4944 : switch (c->name[1]) {
1058 : case '[':
1059 : /* c is an array of arrays. */
1060 569 : u = Utf8String::from_utf8(c->name.begin() + 1, namelen - 1);
1061 569 : if (!(comp = load_class_from_classloader(u, c->classloader)))
1062 0 : return NULL;
1063 569 : break;
1064 :
1065 : case 'L':
1066 : /* c is an array of objects. */
1067 3071 : u = Utf8String::from_utf8(c->name.begin() + 2, namelen - 3);
1068 3071 : if (!(comp = load_class_from_classloader(u, c->classloader)))
1069 0 : return NULL;
1070 : break;
1071 : }
1072 :
1073 : /* If the component type has not been linked, link it now */
1074 :
1075 4944 : assert(!comp || (comp->state & CLASS_LOADED));
1076 :
1077 4944 : if (comp && !(comp->state & CLASS_LINKED))
1078 3 : if (!link_class(comp))
1079 0 : return NULL;
1080 :
1081 : /* Allocate the arraydescriptor */
1082 :
1083 4944 : desc = NEW(arraydescriptor);
1084 :
1085 4944 : if (comp) {
1086 : /* c is an array of references */
1087 3640 : desc->arraytype = ARRAYTYPE_OBJECT;
1088 3640 : desc->componentsize = sizeof(void*);
1089 3640 : desc->dataoffset = OFFSET(java_objectarray_t, data);
1090 :
1091 3640 : compvftbl = comp->vftbl;
1092 :
1093 3640 : if (!compvftbl) {
1094 0 : log_text("Component class has no vftbl");
1095 0 : assert(0);
1096 : }
1097 :
1098 3640 : desc->componentvftbl = compvftbl;
1099 :
1100 3640 : if (compvftbl->arraydesc) {
1101 569 : desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1102 :
1103 569 : if (compvftbl->arraydesc->dimension >= 255) {
1104 1 : exceptions_throw_illegalargumentexception();
1105 1 : return NULL;
1106 : }
1107 :
1108 568 : desc->dimension = compvftbl->arraydesc->dimension + 1;
1109 568 : desc->elementtype = compvftbl->arraydesc->elementtype;
1110 :
1111 : } else {
1112 3071 : desc->elementvftbl = compvftbl;
1113 3071 : desc->dimension = 1;
1114 3071 : desc->elementtype = ARRAYTYPE_OBJECT;
1115 : }
1116 :
1117 : } else {
1118 : /* c is an array of a primitive type */
1119 1304 : switch (c->name[1]) {
1120 : case 'Z':
1121 163 : desc->arraytype = ARRAYTYPE_BOOLEAN;
1122 163 : desc->dataoffset = OFFSET(java_booleanarray_t,data);
1123 163 : desc->componentsize = sizeof(u1);
1124 163 : break;
1125 :
1126 : case 'B':
1127 163 : desc->arraytype = ARRAYTYPE_BYTE;
1128 163 : desc->dataoffset = OFFSET(java_bytearray_t,data);
1129 163 : desc->componentsize = sizeof(u1);
1130 163 : break;
1131 :
1132 : case 'C':
1133 163 : desc->arraytype = ARRAYTYPE_CHAR;
1134 163 : desc->dataoffset = OFFSET(java_chararray_t,data);
1135 163 : desc->componentsize = sizeof(u2);
1136 163 : break;
1137 :
1138 : case 'D':
1139 163 : desc->arraytype = ARRAYTYPE_DOUBLE;
1140 163 : desc->dataoffset = OFFSET(java_doublearray_t,data);
1141 163 : desc->componentsize = sizeof(double);
1142 163 : break;
1143 :
1144 : case 'F':
1145 163 : desc->arraytype = ARRAYTYPE_FLOAT;
1146 163 : desc->dataoffset = OFFSET(java_floatarray_t,data);
1147 163 : desc->componentsize = sizeof(float);
1148 163 : break;
1149 :
1150 : case 'I':
1151 163 : desc->arraytype = ARRAYTYPE_INT;
1152 163 : desc->dataoffset = OFFSET(java_intarray_t,data);
1153 163 : desc->componentsize = sizeof(s4);
1154 163 : break;
1155 :
1156 : case 'J':
1157 163 : desc->arraytype = ARRAYTYPE_LONG;
1158 163 : desc->dataoffset = OFFSET(java_longarray_t,data);
1159 163 : desc->componentsize = sizeof(s8);
1160 163 : break;
1161 :
1162 : case 'S':
1163 163 : desc->arraytype = ARRAYTYPE_SHORT;
1164 163 : desc->dataoffset = OFFSET(java_shortarray_t,data);
1165 163 : desc->componentsize = sizeof(s2);
1166 163 : break;
1167 :
1168 : default:
1169 0 : exceptions_throw_noclassdeffounderror(c->name);
1170 0 : return NULL;
1171 : }
1172 :
1173 1304 : desc->componentvftbl = NULL;
1174 1304 : desc->elementvftbl = NULL;
1175 1304 : desc->dimension = 1;
1176 1304 : desc->elementtype = desc->arraytype;
1177 : }
1178 :
1179 4943 : return desc;
1180 : }
1181 :
1182 : /* linker_create_string_later **************************************************
1183 :
1184 : A hack so we can initialize java.lang.String objects during initialization.
1185 :
1186 : *******************************************************************************/
1187 1210 : void linker_create_string_later(java_object_t **a, Utf8String u)
1188 : {
1189 1210 : deferred_strings.push_back(std::make_pair(a, u));
1190 1210 : }
1191 :
1192 163 : void linker_initialize_deferred_strings()
1193 : {
1194 163 : deferred_strings_vec_t::const_iterator it = deferred_strings.begin();
1195 163 : for (; it != deferred_strings.end(); ++it)
1196 0 : *it->first = JavaString::literal(it->second);
1197 163 : deferred_strings.clear();
1198 163 : }
1199 :
1200 :
1201 : /* linker_compute_subclasses ***************************************************
1202 :
1203 : XXX
1204 :
1205 : ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
1206 : This function needs to take the class renumber lock and stop the
1207 : world during class renumbering. The lock is used in C code which
1208 : is not that performance critical. Whereas JIT code uses critical
1209 : sections to atomically access the class values.
1210 :
1211 : *******************************************************************************/
1212 :
1213 42201 : static void linker_compute_subclasses(classinfo *c)
1214 : {
1215 :
1216 : LOCK_CLASSRENUMBER_LOCK;
1217 :
1218 42201 : if (!(c->flags & ACC_INTERFACE)) {
1219 36189 : c->nextsub = NULL;
1220 36189 : c->sub = NULL;
1221 : #if USES_NEW_SUBTYPE
1222 36189 : c->vftbl->baseval = 1; /* so it does not look like an interface */
1223 : #endif
1224 : }
1225 :
1226 42201 : if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
1227 34559 : c->nextsub = c->super->sub;
1228 34559 : c->super->sub = c;
1229 : }
1230 :
1231 42201 : classvalue = 0;
1232 :
1233 : #if !USES_NEW_SUBTYPE
1234 : /* compute class values */
1235 :
1236 : linker_compute_class_values(class_java_lang_Object);
1237 : #endif
1238 :
1239 : UNLOCK_CLASSRENUMBER_LOCK;
1240 :
1241 42201 : }
1242 :
1243 :
1244 : /* linker_compute_class_values *************************************************
1245 :
1246 : XXX
1247 :
1248 : *******************************************************************************/
1249 :
1250 : #if !USES_NEW_SUBTYPE
1251 : static void linker_compute_class_values(classinfo *c)
1252 : {
1253 : classinfo *subs;
1254 :
1255 : c->vftbl->baseval = ++classvalue;
1256 :
1257 : subs = c->sub;
1258 :
1259 : while (subs) {
1260 : linker_compute_class_values(subs);
1261 :
1262 : subs = subs->nextsub;
1263 : }
1264 :
1265 : c->vftbl->diffval = classvalue - c->vftbl->baseval;
1266 : }
1267 : #endif
1268 :
1269 :
1270 : /* linker_addinterface *********************************************************
1271 :
1272 : Is needed by link_class for adding a VTBL to a class. All
1273 : interfaces implemented by ic are added as well.
1274 :
1275 : RETURN VALUE:
1276 : true.........everything ok
1277 : false........an exception has been thrown
1278 :
1279 : *******************************************************************************/
1280 :
1281 60320 : static bool linker_addinterface(classinfo *c, classinfo *ic)
1282 : {
1283 : s4 j, k;
1284 : vftbl_t *v;
1285 : s4 i;
1286 : classinfo *sc;
1287 : methodinfo *m;
1288 :
1289 60320 : v = c->vftbl;
1290 60320 : i = ic->index;
1291 :
1292 60320 : if (i >= v->interfacetablelength)
1293 0 : vm_abort("Internal error: interfacetable overflow");
1294 :
1295 : /* if this interface has already been added, return immediately */
1296 :
1297 60320 : if (v->interfacetable[-i] != NULL)
1298 7053 : return true;
1299 :
1300 53267 : if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1301 20813 : v->interfacevftbllength[i] = 1;
1302 20813 : v->interfacetable[-i] = MNEW(methodptr, 1);
1303 20813 : v->interfacetable[-i][0] = NULL;
1304 : }
1305 : else {
1306 32454 : v->interfacevftbllength[i] = ic->methodscount;
1307 32454 : v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1308 :
1309 : STATISTICS(count_vftbl_len += sizeof(methodptr) *
1310 : (ic->methodscount + (ic->methodscount == 0)));
1311 :
1312 183414 : for (j = 0; j < ic->methodscount; j++) {
1313 228560 : for (sc = c; sc != NULL; sc = sc->super) {
1314 3155756 : for (k = 0; k < sc->methodscount; k++) {
1315 3078156 : m = &(sc->methods[k]);
1316 :
1317 3078156 : if (method_canoverwrite(m, &(ic->methods[j]))) {
1318 : /* method m overwrites the (abstract) method */
1319 : #if defined(ENABLE_VERIFIER)
1320 : /* Add loading constraints (for the more
1321 : general types of the method
1322 : ic->methods[j]). */
1323 150935 : if (!classcache_add_constraints_for_params(
1324 : c->classloader, ic->classloader,
1325 : &(ic->methods[j])))
1326 : {
1327 0 : return false;
1328 : }
1329 : #endif
1330 :
1331 : /* XXX taken from gcj */
1332 : /* check for ACC_STATIC: IncompatibleClassChangeError */
1333 :
1334 : /* check for !ACC_PUBLIC: IllegalAccessError */
1335 :
1336 : /* check for ACC_ABSTRACT: AbstracMethodError,
1337 : not sure about that one */
1338 :
1339 150935 : v->interfacetable[-i][j] = v->table[m->vftblindex];
1340 150935 : goto foundmethod;
1341 : }
1342 : }
1343 : }
1344 :
1345 : /* If no method was found, insert the AbstractMethodError
1346 : stub. */
1347 :
1348 : #if defined(ENABLE_JIT)
1349 : # if defined(ENABLE_INTRP)
1350 : if (opt_intrp)
1351 : v->interfacetable[-i][j] =
1352 : (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1353 : else
1354 : # endif
1355 25 : v->interfacetable[-i][j] =
1356 25 : (methodptr) (ptrint) &asm_abstractmethoderror;
1357 : #else
1358 : v->interfacetable[-i][j] =
1359 : (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
1360 : #endif
1361 :
1362 : foundmethod:
1363 : ;
1364 : }
1365 : }
1366 :
1367 : /* add superinterfaces of this interface */
1368 :
1369 65298 : for (j = 0; j < ic->interfacescount; j++)
1370 12031 : if (!linker_addinterface(c, ic->interfaces[j]))
1371 0 : return false;
1372 :
1373 : /* everything ok */
1374 :
1375 53267 : return true;
1376 : }
1377 :
1378 :
1379 : /* class_highestinterface ******************************************************
1380 :
1381 : Used by the function link_class to determine the amount of memory
1382 : needed for the interface table.
1383 :
1384 : *******************************************************************************/
1385 :
1386 67494 : static s4 class_highestinterface(classinfo *c)
1387 : {
1388 : s4 h;
1389 : s4 h2;
1390 : s4 i;
1391 :
1392 : /* check for ACC_INTERFACE bit already done in link_class_intern */
1393 :
1394 67494 : h = c->index;
1395 :
1396 86699 : for (i = 0; i < c->interfacescount; i++) {
1397 19205 : h2 = class_highestinterface(c->interfaces[i]);
1398 :
1399 19205 : if (h2 > h)
1400 0 : h = h2;
1401 : }
1402 :
1403 67494 : return h;
1404 495 : }
1405 :
1406 : /*
1407 : * These are local overrides for various environment variables in Emacs.
1408 : * Please do not remove this and leave it at the end of the file, where
1409 : * Emacs will automagically detect them.
1410 : * ---------------------------------------------------------------------
1411 : * Local variables:
1412 : * mode: c++
1413 : * indent-tabs-mode: t
1414 : * c-basic-offset: 4
1415 : * tab-width: 4
1416 : * End:
1417 : * vim:noexpandtab:sw=4:ts=4:
1418 : */
|