LCOV - code coverage report
Current view: top level - vm - linker.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 367 441 83.2 %
Date: 2015-06-10 18:10:59 Functions: 14 14 100.0 %

          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             :  */

Generated by: LCOV version 1.11