LCOV - code coverage report
Current view: top level - vm - loader.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 502 760 66.1 %
Date: 2017-07-14 10:03:36 Functions: 21 27 77.8 %

          Line data    Source code
       1             : /* src/vm/loader.cpp - class loader functions
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             :    Copyright (C) 2009 Theobroma Systems Ltd.
       6             : 
       7             :    This file is part of CACAO.
       8             : 
       9             :    This program is free software; you can redistribute it and/or
      10             :    modify it under the terms of the GNU General Public License as
      11             :    published by the Free Software Foundation; either version 2, or (at
      12             :    your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful, but
      15             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :    General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program; if not, write to the Free Software
      21             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      22             :    02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : 
      27             : #include "vm/loader.hpp"
      28             : #include "config.h"
      29             : 
      30             : #include <cassert>
      31             : #include <cstddef>                      // for size_t
      32             : #include <cstdio>                       // for printf, fprintf
      33             : #include <cstdlib>
      34             : #include <cstring>                      // for memset, strstr, strlen, etc
      35             : #include <list>                         // for _List_iterator, etc
      36             : 
      37             : #include "mm/dumpmemory.hpp"            // for DumpMemory, DumpMemoryArea
      38             : #include "mm/gc.hpp"                    // for heap_hashcode
      39             : 
      40             : #include "native/llni.hpp"
      41             : 
      42             : #include "threads/mutex.hpp"            // for Mutex
      43             : 
      44             : #include "toolbox/hashtable.hpp"        // for hashtable, hashtable_create
      45             : #include "toolbox/list.hpp"             // for DumpList
      46             : #include "toolbox/logging.hpp"          // for log_message_class, etc
      47             : 
      48             : #include "vm/class.hpp"                 // for classinfo, etc
      49             : #include "vm/classcache.hpp"            // for classcache_store, etc
      50             : #include "vm/descriptor.hpp"            // for DescriptorPool, methoddesc, etc
      51             : #include "vm/exceptions.hpp"
      52             : #include "vm/descriptor.hpp"
      53             : #include "vm/field.hpp"                 // for fieldinfo, field_load
      54             : #include "vm/global.hpp"
      55             : #include "vm/globals.hpp"               // for class_java_io_Serializable, etc
      56             : #include "vm/hook.hpp"                  // for class_loaded
      57             : #include "vm/javaobjects.hpp"           // for java_lang_ClassLoader
      58             : #include "vm/linker.hpp"
      59             : #include "vm/method.hpp"                // for methodinfo, etc
      60             : #include "vm/options.hpp"               // for opt_verify, loadverbose, etc
      61             : #include "vm/package.hpp"               // for Package
      62             : #include "vm/primitive.hpp"             // for Primitive
      63             : #include "vm/references.hpp"            // for constant_FMIref, etc
      64             : #include "vm/resolve.hpp"
      65             : #include "vm/rt-timing.hpp"
      66             : #include "vm/statistics.hpp"
      67             : #include "vm/string.hpp"                // for JavaString
      68             : #include "vm/suck.hpp"                  // for suck_check_classbuffer_size, etc
      69             : #include "vm/types.hpp"                 // for u2, u1, u4, s4
      70             : #include "vm/vm.hpp"                    // for VM, vm_call_method
      71             : #include "vm/zip.hpp"                   // for hashtable_zipfile_entry
      72             : 
      73             : #include "vm/jit/builtin.hpp"
      74             : #include "vm/jit/stubs.hpp"             // for NativeStub
      75             : 
      76             : #if defined(ENABLE_JAVASE)
      77             : # include "vm/annotation.hpp"
      78             : # include "vm/stackmap.hpp"
      79             : #endif
      80             : 
      81             : using namespace cacao;
      82             : 
      83             : struct classinfo;
      84             : 
      85             : 
      86             : STAT_REGISTER_VAR(int,count_class_loads,0,"class loads","Number of class loads")
      87             : 
      88             : STAT_DECLARE_GROUP(memory_stat)
      89             : STAT_REGISTER_SUM_SUBGROUP(info_struct_stat,"info structs","info struct usage",memory_stat)
      90             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_classinfo,0,"size classinfo","classinfo",info_struct_stat) // sizeof(classinfo)?
      91             : STAT_REGISTER_GROUP_VAR(int,size_fieldinfo,0,"size fieldinfo","fieldinfo",info_struct_stat) // sizeof(fieldinfo)?
      92             : STAT_REGISTER_GROUP_VAR(int,size_methodinfo,0,"size methodinfo","methodinfo",info_struct_stat) // sizeof(methodinfo)?
      93             : 
      94             : 
      95             : STAT_REGISTER_SUM_SUBGROUP(misc_code_stat,"misc structs","misc struct usage",memory_stat)
      96             : STAT_REGISTER_GROUP_VAR(int,count_const_pool_len,0,"const pool len","constant pool",misc_code_stat)
      97             : STAT_REGISTER_GROUP_VAR(int,count_classref_len,0,"classref len","classref",misc_code_stat)
      98             : STAT_REGISTER_GROUP_VAR(int,count_parsed_desc_len,0,"parsed desc len","parsed descriptors",misc_code_stat)
      99             : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_vftbl_len,0,"vftbl len","vftbl",misc_code_stat)
     100             : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_cstub_len,0,"cstub len","compiler stubs",misc_code_stat)
     101             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stub_native,0,"stub native","native stubs",misc_code_stat)
     102             : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_utf_len,0,"utf len","utf",misc_code_stat)
     103             : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_vmcode_len,0,"vmcode len","vmcode",misc_code_stat)
     104             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stack_map,0,"stack map","stack map",misc_code_stat)
     105             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_string,0,"string","string",misc_code_stat)
     106             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_threadobject,0,"threadobject","threadobject",misc_code_stat)
     107             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_thread_index_t,0,"size_thread_index_t","thread index",misc_code_stat)
     108             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_stacksize,0,"size_stacksize","stack size",misc_code_stat)
     109             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_record,0,"size_lock_record","lock record",misc_code_stat)
     110             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_hashtable,0,"size_lock_hashtable","lock hashtable",misc_code_stat)
     111             : STAT_REGISTER_GROUP_VAR_EXTERN(int,size_lock_waiter,0,"size_lock_waiter","lock waiter",misc_code_stat)
     112             : 
     113             : 
     114             : /* global variables ***********************************************************/
     115             : 
     116             : static hashtable *hashtable_classloader;
     117             : 
     118             : 
     119             : enum ConstantPoolPlacement { ConstantPool };
     120             : 
     121     1289140 : inline void *operator new(std::size_t size, ConstantPoolPlacement) {
     122             :         STATISTICS(count_const_pool_len += size);
     123             : 
     124     1289140 :         return mem_alloc(size);
     125             : }
     126             : 
     127         165 : const ClassFileVersion ClassFileVersion::CACAO_VERSION(MAJOR_VERSION, MINOR_VERSION);
     128         165 : const ClassFileVersion ClassFileVersion::JDK_7(51, 0);
     129             : 
     130             : 
     131             : /* loader_preinit **************************************************************
     132             : 
     133             :    Initializes the classpath list and loads classes required for the
     134             :    primitive table.
     135             : 
     136             :    NOTE: Exceptions thrown during VM initialization are caught in the
     137             :          exception functions themselves.
     138             : 
     139             : *******************************************************************************/
     140             : 
     141         163 : void loader_preinit(void)
     142             : {
     143         163 :         TRACESUBSYSTEMINITIALIZATION("loader_preinit");
     144             : 
     145             :         // Get current list of classpath entries.
     146         163 :         SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
     147             : 
     148             :         /* Initialize the monitor pointer for zip/jar file locking. */
     149             : 
     150         490 :         for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
     151         327 :                 list_classpath_entry* lce = *it;
     152             : 
     153         327 :                 if (lce->type == CLASSPATH_ARCHIVE)
     154         164 :                         lce->mutex = new Mutex();
     155             :         }
     156             : 
     157             :         /* initialize classloader hashtable, 10 entries should be enough */
     158             : 
     159         163 :         hashtable_classloader = NEW(hashtable);
     160         163 :         hashtable_create(hashtable_classloader, 10);
     161             : 
     162             :         /* Load the most basic classes. */
     163             : 
     164         163 :         assert(VM::get_current()->is_initializing() == true);
     165             : 
     166         163 :         class_java_lang_Object     = load_class_bootstrap(utf8::java_lang_Object);
     167             : 
     168             : #if defined(ENABLE_JAVASE)
     169         163 :         class_java_lang_Cloneable  = load_class_bootstrap(utf8::java_lang_Cloneable);
     170         163 :         class_java_io_Serializable = load_class_bootstrap(utf8::java_io_Serializable);
     171             : #endif
     172         163 : }
     173             : 
     174             : 
     175             : /* loader_init *****************************************************************
     176             : 
     177             :    Loads all classes required in the VM.
     178             : 
     179             :    NOTE: Exceptions thrown during VM initialization are caught in the
     180             :          exception functions themselves.
     181             : 
     182             : *******************************************************************************/
     183             : 
     184         163 : void loader_init(void)
     185             : {
     186         163 :         TRACESUBSYSTEMINITIALIZATION("loader_init");
     187             : 
     188             :         /* Load primitive-type wrapping classes. */
     189             : 
     190         163 :         assert(VM::get_current()->is_initializing() == true);
     191             : 
     192             : #if defined(ENABLE_JAVASE)
     193         163 :         class_java_lang_Void       = load_class_bootstrap(utf8::java_lang_Void);
     194             : #endif
     195             : 
     196         163 :         class_java_lang_Boolean    = load_class_bootstrap(utf8::java_lang_Boolean);
     197         163 :         class_java_lang_Byte       = load_class_bootstrap(utf8::java_lang_Byte);
     198         163 :         class_java_lang_Character  = load_class_bootstrap(utf8::java_lang_Character);
     199         163 :         class_java_lang_Short      = load_class_bootstrap(utf8::java_lang_Short);
     200         163 :         class_java_lang_Integer    = load_class_bootstrap(utf8::java_lang_Integer);
     201         163 :         class_java_lang_Long       = load_class_bootstrap(utf8::java_lang_Long);
     202         163 :         class_java_lang_Float      = load_class_bootstrap(utf8::java_lang_Float);
     203         163 :         class_java_lang_Double     = load_class_bootstrap(utf8::java_lang_Double);
     204             : 
     205             :         /* Load important system classes. */
     206             : 
     207         163 :         class_java_lang_Class      = load_class_bootstrap(utf8::java_lang_Class);
     208         163 :         class_java_lang_String     = load_class_bootstrap(utf8::java_lang_String);
     209             : 
     210             : #if defined(ENABLE_JAVASE)
     211             :         class_java_lang_ClassLoader =
     212         163 :                 load_class_bootstrap(utf8::java_lang_ClassLoader);
     213             : 
     214             :         class_java_lang_SecurityManager =
     215         163 :                 load_class_bootstrap(utf8::java_lang_SecurityManager);
     216             : #endif
     217             : 
     218             :         class_java_lang_System     =
     219         163 :                 load_class_bootstrap(Utf8String::from_utf8("java/lang/System"));
     220             : 
     221             :         class_java_lang_Thread     =
     222         163 :                 load_class_bootstrap(Utf8String::from_utf8("java/lang/Thread"));
     223             : 
     224             : #if defined(ENABLE_JAVASE)
     225             :         class_java_lang_ThreadGroup =
     226         163 :                 load_class_bootstrap(utf8::java_lang_ThreadGroup);
     227             : #endif
     228             : 
     229         163 :         class_java_lang_Throwable  = load_class_bootstrap(utf8::java_lang_Throwable);
     230             : 
     231             : #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
     232             :         class_java_lang_VMSystem   =
     233         163 :                 load_class_bootstrap(Utf8String::from_utf8("java/lang/VMSystem"));
     234             : 
     235             :         class_java_lang_VMThread   =
     236         163 :                 load_class_bootstrap(Utf8String::from_utf8("java/lang/VMThread"));
     237             : 
     238             :         class_java_lang_VMThrowable =
     239         163 :                 load_class_bootstrap(Utf8String::from_utf8("java/lang/VMThrowable"));
     240             : #endif
     241             : 
     242             :         /* Important system exceptions. */
     243             : 
     244         163 :         class_java_lang_Exception  = load_class_bootstrap(utf8::java_lang_Exception);
     245             : 
     246             :         class_java_lang_ClassNotFoundException =
     247         163 :                 load_class_bootstrap(utf8::java_lang_ClassNotFoundException);
     248             : 
     249             :         class_java_lang_RuntimeException =
     250         163 :                 load_class_bootstrap(utf8::java_lang_RuntimeException);
     251             : 
     252             :         /* Some classes which may be used often. */
     253             : 
     254             : #if defined(ENABLE_JAVASE)
     255         163 :         class_java_lang_StackTraceElement      = load_class_bootstrap(utf8::java_lang_StackTraceElement);
     256             : 
     257         163 :         class_java_lang_reflect_Constructor    = load_class_bootstrap(utf8::java_lang_reflect_Constructor);
     258         163 :         class_java_lang_reflect_Field          = load_class_bootstrap(utf8::java_lang_reflect_Field);
     259         163 :         class_java_lang_reflect_Method         = load_class_bootstrap(utf8::java_lang_reflect_Method);
     260             : 
     261             : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
     262         163 :         class_java_lang_reflect_VMConstructor  = load_class_bootstrap(utf8::java_lang_reflect_VMConstructor);
     263         163 :         class_java_lang_reflect_VMField        = load_class_bootstrap(utf8::java_lang_reflect_VMField);
     264         163 :         class_java_lang_reflect_VMMethod       = load_class_bootstrap(utf8::java_lang_reflect_VMMethod);
     265             : # endif
     266             : 
     267         163 :         class_java_security_PrivilegedAction   = load_class_bootstrap(Utf8String::from_utf8("java/security/PrivilegedAction"));
     268             : 
     269         163 :         class_java_util_HashMap                = load_class_bootstrap(Utf8String::from_utf8("java/util/HashMap"));
     270         163 :         class_java_util_Vector                 = load_class_bootstrap(utf8::java_util_Vector);
     271             : 
     272             : # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
     273             :         class_sun_misc_Signal                     = load_class_bootstrap(Utf8String::from_utf8("sun/misc/Signal"));
     274             :         class_sun_reflect_MagicAccessorImpl       = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/MagicAccessorImpl"));
     275             :         class_sun_reflect_MethodAccessorImpl      = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/MethodAccessorImpl"));
     276             :         class_sun_reflect_ConstructorAccessorImpl = load_class_bootstrap(Utf8String::from_utf8("sun/reflect/ConstructorAccessorImpl"));
     277             : # endif
     278             : 
     279             :         arrayclass_java_lang_Object =
     280         163 :                 load_class_bootstrap(Utf8String::from_utf8("[Ljava/lang/Object;"));
     281             : 
     282             : # if defined(ENABLE_ANNOTATIONS)
     283             :         /* needed by annotation support */
     284             :         class_sun_reflect_ConstantPool =
     285         163 :                 load_class_bootstrap(Utf8String::from_utf8("sun/reflect/ConstantPool"));
     286             : 
     287             : #  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
     288             :         /* needed by GNU Classpaths annotation support */
     289             :         class_sun_reflect_annotation_AnnotationParser =
     290         163 :                 load_class_bootstrap(Utf8String::from_utf8("sun/reflect/annotation/AnnotationParser"));
     291             : #  endif
     292             : # endif
     293             : #endif
     294         163 : }
     295             : 
     296             : 
     297             : /* loader_hashtable_classloader_add ********************************************
     298             : 
     299             :    Adds an entry to the classloader hashtable.
     300             : 
     301             :    REMEMBER: Also use this to register native loaders!
     302             : 
     303             : *******************************************************************************/
     304             : 
     305        3826 : classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
     306             : {
     307             :         hashtable_classloader_entry *cle;
     308             :         u4   key;
     309             :         u4   slot;
     310             : 
     311        3826 :         if (cl == NULL)
     312         997 :                 return NULL;
     313             : 
     314        2829 :         hashtable_classloader->mutex->lock();
     315             : 
     316             :         LLNI_CRITICAL_START;
     317             : 
     318             :         /* key for entry is the hashcode of the classloader;
     319             :            aligned to 16-byte boundaries */
     320             : 
     321        2829 :         key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
     322        2829 :         slot = key & (hashtable_classloader->size - 1);
     323        2829 :         cle  = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
     324             : 
     325             :         /* search hashchain for existing entry */
     326             : 
     327        5661 :         while (cle) {
     328        2671 :                 if (cle->object == LLNI_DIRECT(cl))
     329        2668 :                         break;
     330             : 
     331           3 :                 cle = cle->hashlink;
     332             :         }
     333             : 
     334             :         LLNI_CRITICAL_END;
     335             : 
     336             :         /* if no classloader was found, we create a new entry here */
     337             : 
     338        2829 :         if (cle == NULL) {
     339         161 :                 cle = NEW(hashtable_classloader_entry);
     340             : 
     341             : #if defined(ENABLE_GC_CACAO)
     342             :                 /* register the classloader object with the GC */
     343             : 
     344             :                 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
     345             : #endif
     346             : 
     347             :                 LLNI_CRITICAL_START;
     348             : 
     349         161 :                 cle->object = LLNI_DIRECT(cl);
     350             : 
     351             :                 LLNI_CRITICAL_END;
     352             : 
     353             : /*#define LOADER_DEBUG_CLASSLOADER*/
     354             : #ifdef LOADER_DEBUG_CLASSLOADER
     355             :                 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
     356             :                 class_print(LLNI_vftbl_direct(cl)->class);
     357             :                 printf("\n");
     358             :                 fflush(stdout);
     359             : #endif
     360             : 
     361             :                 /* insert entry into hashtable */
     362             : 
     363         161 :                 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
     364         161 :                 hashtable_classloader->ptr[slot] = cle;
     365             : 
     366             :                 /* update number of entries */
     367             : 
     368         161 :                 hashtable_classloader->entries++;
     369             :         }
     370             : 
     371        2829 :         hashtable_classloader->mutex->unlock();
     372             : 
     373             : #if defined(ENABLE_HANDLES)
     374             :         return cle;
     375             : #else
     376        2829 :         return cl;
     377             : #endif
     378             : }
     379             : 
     380             : 
     381             : /* loader_hashtable_classloader_find *******************************************
     382             : 
     383             :    Find an entry in the classloader hashtable.
     384             : 
     385             : *******************************************************************************/
     386             : 
     387           0 : classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
     388             : {
     389             :         hashtable_classloader_entry *cle;
     390             :         u4   key;
     391             :         u4   slot;
     392             : 
     393           0 :         if (cl == NULL)
     394           0 :                 return NULL;
     395             : 
     396             :         LLNI_CRITICAL_START;
     397             : 
     398             :         /* key for entry is the hashcode of the classloader;
     399             :            aligned to 16-byte boundaries */
     400             : 
     401           0 :         key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
     402           0 :         slot = key & (hashtable_classloader->size - 1);
     403           0 :         cle  = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
     404             : 
     405             :         /* search hashchain for existing entry */
     406             : 
     407           0 :         while (cle) {
     408           0 :                 if (cle->object == LLNI_DIRECT(cl))
     409           0 :                         break;
     410             : 
     411           0 :                 cle = cle->hashlink;
     412             :         }
     413             : 
     414             : #ifdef LOADER_DEBUG_CLASSLOADER
     415             :         if (cle == NULL) {
     416             :                 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
     417             :                 class_print(LLNI_vftbl_direct(cl)->class);
     418             :                 printf("\n");
     419             :                 fflush(stdout);
     420             :         }
     421             : #endif
     422             : 
     423             :         LLNI_CRITICAL_END;
     424             : 
     425             : #if defined(ENABLE_HANDLES)
     426             :         return cle;
     427             : #else
     428           0 :         return cl;
     429             : #endif
     430             : }
     431             : 
     432             : 
     433             : /* loader_load_all_classes *****************************************************
     434             : 
     435             :    Loads all classes specified in the BOOTCLASSPATH.
     436             : 
     437             : *******************************************************************************/
     438             : 
     439           0 : void loader_load_all_classes(void)
     440             : {
     441             :         // Get current list of classpath entries.
     442           0 :         SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
     443             : 
     444           0 :         for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
     445           0 :                 list_classpath_entry* lce = *it;
     446             : 
     447             : #if defined(ENABLE_ZLIB)
     448           0 :                 if (lce->type == CLASSPATH_ARCHIVE) {
     449             :                         /* get the classes hashtable */
     450             : 
     451           0 :                         ZipFile *zip = lce->zip;
     452             : 
     453           0 :                         for (ZipFile::Iterator it = zip->begin(), end = zip->end(); it != end; ++it) {
     454           0 :                                 const ZipFileEntry& entry = *it;
     455             : 
     456           0 :                                 Utf8String filename = entry.filename;
     457             : 
     458             :                                 // skip all entries in META-INF, .properties and .png files
     459             : 
     460           0 :                                 if (!strncmp(filename.begin(), "META-INF", strlen("META-INF")) ||
     461             :                                     strstr(filename.begin(), ".properties") ||
     462             :                                     strstr(filename.begin(), ".png"))
     463           0 :                                         continue;
     464             : 
     465             :                                 // load class from bootstrap classloader
     466             : 
     467           0 :                                 if (!load_class_bootstrap(filename)) {
     468           0 :                                         err() << "Error loading class: '" << filename << "'" << nl;
     469             : 
     470             : #ifndef NDEBUG
     471             :                                         // print out exception and cause
     472             : 
     473           0 :                                         exceptions_print_current_exception();
     474             : #endif
     475             :                                 }
     476             :                         }
     477             : 
     478             :                 } else {
     479             : #endif
     480             : #if defined(ENABLE_ZLIB)
     481             :                 }
     482             : #endif
     483             :         }
     484           0 : }
     485             : 
     486             : 
     487             : /* loader_skip_attribute_body **************************************************
     488             : 
     489             :    Skips an attribute the attribute_name_index has already been read.
     490             : 
     491             :    attribute_info {
     492             :        u2 attribute_name_index;
     493             :        u4 attribute_length;
     494             :        u1 info[attribute_length];
     495             :    }
     496             : 
     497             : *******************************************************************************/
     498             : 
     499        7171 : bool loader_skip_attribute_body(ClassBuffer& cb)
     500             : {
     501        7171 :         if (!cb.check_size(4))
     502           0 :                 return false;
     503             : 
     504        7171 :         u4 attribute_length = cb.read_u4();
     505             : 
     506        7171 :         if (!cb.check_size(attribute_length))
     507           0 :                 return false;
     508             : 
     509        7171 :         cb.skip_nbytes(attribute_length);
     510             : 
     511        7171 :         return true;
     512             : }
     513             : 
     514             : 
     515             : /* load_constantpool ***********************************************************
     516             : 
     517             :    Loads the constantpool of a class, the entries are transformed into
     518             :    a simpler format by resolving references (a detailed overview of
     519             :    the compact structures can be found in global.h).
     520             : 
     521             : *******************************************************************************/
     522             : 
     523             : // The following structures are used to save information which cannot be
     524             : // processed during the first pass. After the complete constantpool has
     525             : // been traversed the references can be resolved (only in specific order).
     526             : 
     527             : /// CONSTANT_Class entries
     528      337618 : struct ForwardClass {
     529             :         uint16_t this_index;
     530             :         uint16_t name_index;
     531             : };
     532             : 
     533             : /// CONSTANT_String
     534      126517 : struct ForwardString {
     535             :         uint16_t this_index;
     536             :         uint16_t utf8_index;
     537             : };
     538             : 
     539             : /// CONSTANT_NameAndType
     540      576467 : struct ForwardNameAndType {
     541             :         uint16_t this_index;
     542             :         uint16_t name_index;
     543             :         uint16_t type_index;
     544             : };
     545             : 
     546             : /// CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref
     547      668732 : struct ForwardFieldMethInt {
     548             :         uint16_t this_index;
     549             :         uint8_t  tag;
     550             :         uint16_t class_index;
     551             :         uint16_t nameandtype_index;
     552             : };
     553             : 
     554             : /// CONSTANT_MethodHandle
     555           0 : struct ForwardMethodHandle {
     556             :         uint16_t this_index;
     557             :         uint8_t  reference_kind;
     558             :         uint16_t reference_index;
     559             : };
     560             : 
     561             : /// CONSTANT_MethodType
     562           0 : struct ForwardMethodType {
     563             :         uint16_t this_index;
     564             :         uint16_t descriptor_index;
     565             : };
     566             : 
     567             : /// CONSTANT_InvokeDynamic
     568           0 : struct ForwardInvokeDynamic {
     569             :         uint16_t this_index;
     570             :         uint16_t bootstrap_method_attr_index;
     571             :         uint16_t name_and_type_index;
     572             : };
     573             : 
     574       71580 : struct ForwardReferences {
     575             :         DumpList<ForwardClass>         classes;
     576             :         DumpList<ForwardString>        strings;
     577             :         DumpList<ForwardNameAndType>   nameandtypes;
     578             :         DumpList<ForwardFieldMethInt>  fieldmethints;
     579             :         DumpList<ForwardMethodHandle>  methodhandles;
     580             :         DumpList<ForwardMethodType>    methodtypes;
     581             :         DumpList<ForwardInvokeDynamic> invokedynamics;
     582             : };
     583             : 
     584             : 
     585       35790 : static bool load_constantpool(ClassBuffer& cb, ForwardReferences& fwd, DescriptorPool& descpool) {
     586       35790 :         classinfo *c = cb.get_class();
     587             : 
     588             :         // number of entries in the constant_pool table plus one
     589       35790 :         if (!cb.check_size(2))
     590           0 :                 return false;
     591             : 
     592       35790 :         u2 cpcount = c->cpcount = cb.read_u2();
     593             : 
     594             :         // allocate memory
     595       35790 :         u1    *cptags  = c->cptags  = MNEW(u1, cpcount);
     596       35790 :         void **cpinfos = c->cpinfos = MNEW(void*, cpcount);
     597             : 
     598             :         // NOTE: MNEW zero initializes allcated memory, 
     599             :         //       cptags and cpinfos require this
     600             : 
     601       35790 :         if (cpcount < 1) {
     602           0 :                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
     603           0 :                 return false;
     604             :         }
     605             : 
     606             :         STATISTICS(count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount);
     607             : 
     608             :         /******* first pass *******/
     609             :         // entries which cannot be resolved now are written into
     610             :         // temporary structures and traversed again later
     611             : 
     612       35790 :         u2 idx = 1;
     613             : 
     614     3870339 :         while (idx < cpcount) {
     615             :                 // get constant type
     616     3798759 :                 if (!cb.check_size(1))
     617           0 :                         return false;
     618             : 
     619     3798759 :                 ConstantPoolTag tag = (ConstantPoolTag) cb.read_u1();
     620             : 
     621     3798759 :                 switch (tag) {
     622             :                 case CONSTANT_Class: {
     623             :                         // reference to CONSTANT_Utf8 with class name
     624      337618 :                         if (!cb.check_size(2))
     625           0 :                                 return false;
     626             : 
     627      337618 :                         uint16_t name_index = cb.read_u2();
     628             : 
     629      337618 :                         ForwardClass f = { idx, name_index };
     630             : 
     631      337618 :                         fwd.classes.push_back(f);
     632             : 
     633      337618 :                         idx++;
     634      337618 :                         break;
     635             :                 }
     636             : 
     637             :                 case CONSTANT_String: {
     638             :                         // reference to CONSTANT_Utf8_info with string characters
     639      126517 :                         if (!cb.check_size(2))
     640           0 :                                 return false;
     641             : 
     642      126517 :                         uint16_t utf8_index = cb.read_u2();
     643             : 
     644      126517 :                         ForwardString f = { idx, utf8_index };
     645             : 
     646      126517 :                         fwd.strings.push_back(f);
     647             : 
     648      126517 :                         idx++;
     649      126517 :                         break;
     650             :                 }
     651             : 
     652             :                 case CONSTANT_NameAndType: {
     653      576467 :                         if (!cb.check_size(2 + 2))
     654           0 :                                 return false;
     655             : 
     656             :                         // reference to CONSTANT_Utf8_info containing simple name
     657      576467 :                         uint16_t name_index = cb.read_u2();
     658             : 
     659             :                         // reference to CONSTANT_Utf8_info containing field or method descriptor
     660      576467 :                         uint16_t type_index = cb.read_u2();
     661             : 
     662      576467 :                         ForwardNameAndType f = { idx, name_index, type_index };
     663             : 
     664      576467 :                         fwd.nameandtypes.push_back(f);
     665             : 
     666      576467 :                         idx++;
     667      576467 :                         break;
     668             :                 }
     669             : 
     670             :                 case CONSTANT_Fieldref:
     671             :                 case CONSTANT_Methodref:
     672             :                 case CONSTANT_InterfaceMethodref: {
     673      668732 :                         if (!cb.check_size(2 + 2))
     674           0 :                                 return false;
     675             : 
     676             :                         // class or interface type that contains the declaration of the field or method
     677      668732 :                         uint16_t class_index = cb.read_u2();
     678             : 
     679             :                         // name and descriptor of the field or method
     680      668732 :                         uint16_t nameandtype_index = cb.read_u2();
     681             : 
     682      668732 :                         ForwardFieldMethInt f = { idx, tag, class_index, nameandtype_index };
     683             : 
     684      668732 :                         fwd.fieldmethints.push_back(f);
     685             : 
     686      668732 :                         cptags[idx] = tag;
     687             : 
     688      668732 :                         idx++;
     689      668732 :                         break;
     690             :                 }
     691             : 
     692             :                 case CONSTANT_Integer: {
     693       28453 :                         if (!cb.check_size(4))
     694           0 :                                 return false;
     695             : 
     696       28453 :                         cptags[idx]  = CONSTANT_Integer;
     697       28453 :                         cpinfos[idx] = new (ConstantPool) int32_t(cb.read_s4());
     698             : 
     699       28453 :                         idx++;
     700       28453 :                         break;
     701             :                 }
     702             : 
     703             :                 case CONSTANT_Float: {
     704        2501 :                         if (!cb.check_size(4))
     705           0 :                                 return false;
     706             : 
     707        2501 :                         cptags[idx]  = CONSTANT_Float;
     708        2501 :                         cpinfos[idx] = new (ConstantPool) float(cb.read_float());
     709             : 
     710        2501 :                         idx++;
     711        2501 :                         break;
     712             :                 }
     713             : 
     714             :                 case CONSTANT_Long: {
     715       10958 :                         if (!cb.check_size(8))
     716           0 :                                 return false;
     717             : 
     718       10958 :                         cptags[idx]  = CONSTANT_Long;
     719       10958 :                         cpinfos[idx] = new (ConstantPool) int64_t(cb.read_s8());
     720             : 
     721       10958 :                         idx += 2;
     722       10958 :                         if (idx > cpcount) {
     723           0 :                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
     724           0 :                                 return false;
     725             :                         }
     726       10958 :                         break;
     727             :                 }
     728             : 
     729             :                 case CONSTANT_Double: {
     730        2033 :                         if (!cb.check_size(8))
     731           0 :                                 return false;
     732             : 
     733        2033 :                         cptags[idx]  = CONSTANT_Double;
     734        2033 :                         cpinfos[idx] = new (ConstantPool) double(cb.read_double());
     735             : 
     736        2033 :                         idx += 2;
     737        2033 :                         if (idx > cpcount) {
     738           0 :                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
     739           0 :                                 return false;
     740             :                         }
     741        2033 :                         break;
     742             :                 }
     743             : 
     744             :                 case CONSTANT_Utf8: {
     745     2045480 :                         if (!cb.check_size(2))
     746           0 :                                 return false;
     747             : 
     748             :                         // number of bytes in the bytes array (not string-length)
     749     2045480 :                         uint16_t length = cb.read_u2();
     750             : 
     751             :                         // validate the string
     752     2045480 :                         if (!cb.check_size(length))
     753           0 :                                 return false;
     754             : 
     755     2045480 :                         Utf8String u = Utf8String::from_utf8((char *) cb.get_data(), length);
     756             : #ifdef ENABLE_VERIFIER
     757     2045480 :                         if (opt_verify && u == NULL) {
     758           0 :                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
     759           0 :                                 return false;
     760             :                         }
     761             : #endif
     762     2045480 :                         cptags[idx]  = CONSTANT_Utf8;
     763     2045480 :                         cpinfos[idx] = u.c_ptr();
     764             : 
     765             :                         // skip bytes of the string (buffer size check above)
     766     2045480 :                         cb.skip_nbytes(length);
     767     2045480 :                         idx++;
     768     2045480 :                         break;
     769             :                 }
     770             : 
     771             :                 case CONSTANT_MethodHandle: {
     772           0 :                         if (cb.version() < ClassFileVersion::JDK_7)
     773           0 :                                 goto unsupported_tag;
     774             : 
     775           0 :                         if (!cb.check_size(1 + 2))
     776           0 :                                 return false;
     777             : 
     778           0 :                         uint8_t  reference_kind  = cb.read_u1();
     779           0 :                         uint16_t reference_index = cb.read_u2();
     780             : 
     781           0 :                         ForwardMethodHandle f = { idx, reference_kind, reference_index };
     782             : 
     783           0 :                         fwd.methodhandles.push_back(f);
     784             : 
     785           0 :                         idx++;
     786           0 :                         break;
     787             :                 }
     788             : 
     789             :                 case CONSTANT_MethodType: {
     790           0 :                         if (cb.version() < ClassFileVersion::JDK_7)
     791           0 :                                 goto unsupported_tag;
     792             : 
     793           0 :                         if (!cb.check_size(2))
     794           0 :                                 return false;
     795             : 
     796           0 :                         uint16_t descriptor_index = cb.read_u2();
     797             : 
     798           0 :                         ForwardMethodType f = { idx, descriptor_index };
     799             : 
     800           0 :                         fwd.methodtypes.push_front(f);
     801             : 
     802           0 :                         idx++;
     803           0 :                         break;
     804             :                 }
     805             : 
     806             :                 case CONSTANT_InvokeDynamic: {
     807           0 :                         if (cb.version() < ClassFileVersion::JDK_7)
     808           0 :                                 goto unsupported_tag;
     809             : 
     810           0 :                         if (!cb.check_size(2 + 2))
     811           0 :                                 return false;
     812             : 
     813           0 :                         uint16_t bootstrap_method_attr_index = cb.read_u2();
     814           0 :                         uint16_t name_and_type_index         = cb.read_u2();
     815             : 
     816           0 :                         ForwardInvokeDynamic f = { idx, bootstrap_method_attr_index, name_and_type_index };
     817             : 
     818           0 :                         fwd.invokedynamics.push_front(f);
     819             : 
     820           0 :                         idx++;
     821           0 :                         break;
     822             :                 }
     823             : 
     824             :                 unsupported_tag:
     825           0 :                         exceptions_throw_classformaterror(c, "Class file version does not support constant tag %u in class file %s", tag, c->name.begin());
     826           0 :                         return false;
     827             : 
     828             :                 default:
     829           0 :                         exceptions_throw_classformaterror(c, "Illegal constant pool type '%u'", tag);
     830           0 :                         return false;
     831             :                 }  /* end switch */
     832             :         } /* end while */
     833             : 
     834             :         /* resolve entries in temporary structures */
     835             : 
     836      409198 :         for (DumpList<ForwardClass>::iterator it  = fwd.classes.begin(),
     837       35790 :                                               end = fwd.classes.end(); it != end; ++it) {
     838      337618 :                 Utf8String name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
     839             : 
     840      337618 :                 if (!name)
     841           0 :                         return false;
     842             : 
     843             : #ifdef ENABLE_VERIFIER
     844      337618 :                 if (opt_verify && !name.is_valid_name()) {
     845           0 :                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
     846           0 :                         return false;
     847             :                 }
     848             : #endif
     849             : 
     850             :                 // add all class references to the descriptor_pool
     851             : 
     852      337618 :                 if (!descpool.add_class(name))
     853           0 :                         return false;
     854             : 
     855             :                 // the classref is created later
     856      337618 :                 cptags[it->this_index]  = CONSTANT_ClassName;
     857      337618 :                 cpinfos[it->this_index] = name;
     858             :         }
     859             : 
     860      198097 :         for (DumpList<ForwardString>::iterator it  = fwd.strings.begin(),
     861       35790 :                                                    end = fwd.strings.end(); it != end; ++it) {
     862      126517 :                 Utf8String text = (utf*) class_getconstant(c, it->utf8_index, CONSTANT_Utf8);
     863             : 
     864      126517 :                 if (!text)
     865           0 :                         return false;
     866             : 
     867             :                 // resolve utf-string
     868      126517 :                 cptags[it->this_index]  = CONSTANT_String;
     869      126517 :                 cpinfos[it->this_index] = text;
     870             :         }
     871             : 
     872      648047 :         for (DumpList<ForwardNameAndType>::iterator it  = fwd.nameandtypes.begin(),
     873       35790 :                                                         end = fwd.nameandtypes.end(); it != end; ++it) {
     874             :                 // resolve simple name and descriptor
     875      576467 :                 Utf8String name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
     876      576467 :                 if (!name)
     877           0 :                         return false;
     878             : 
     879      576467 :                 Utf8String descriptor = (utf*) class_getconstant(c, it->type_index, CONSTANT_Utf8);
     880      576467 :                 if (!descriptor)
     881           0 :                         return false;
     882             : 
     883             : #ifdef ENABLE_VERIFIER
     884      576467 :                 if (opt_verify) {
     885             :                         // check name
     886      576467 :                         if (!name.is_valid_name()) {
     887           0 :                                 exceptions_throw_classformaterror(c, "Illegal field or method name \"%s\"", name.begin());
     888           0 :                                 return false;
     889             :                         }
     890             : 
     891             :                         // disallow referencing <clinit> among others
     892      576467 :                         if (name[0] == '<' && name != utf8::init) {
     893           0 :                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
     894           0 :                                 return false;
     895             :                         }
     896             :                 }
     897             : #endif // ENABLE_VERIFIER
     898             : 
     899      576467 :                 cptags[it->this_index]  = CONSTANT_NameAndType;
     900      576467 :                 cpinfos[it->this_index] = new (ConstantPool) constant_nameandtype(name, descriptor);
     901             :         }
     902             : 
     903      740312 :         for (DumpList<ForwardFieldMethInt>::iterator it  = fwd.fieldmethints.begin(),
     904       35790 :                                                      end = fwd.fieldmethints.end(); it != end; ++it) {
     905             :                 // resolve simple name and descriptor
     906             : 
     907             :                 constant_nameandtype *nat = (constant_nameandtype*) class_getconstant(c,
     908             :                                                                                                                                       it->nameandtype_index,
     909      668732 :                                                                                                                                       CONSTANT_NameAndType);
     910      668732 :                 if (!nat)
     911           0 :                         return false;
     912             : 
     913             :                 // add all descriptors in {Field,Method}ref to the descriptor_pool
     914             : 
     915      668732 :                 switch (it->tag) {
     916             :                 case CONSTANT_Fieldref:
     917      100939 :                         if (!descpool.add_field(nat->descriptor))
     918           0 :                                 return false;
     919      100939 :                         break;
     920             :                 case CONSTANT_Methodref:
     921             :                 case CONSTANT_InterfaceMethodref:
     922      567793 :                         if (descpool.add_method(nat->descriptor) == -1)
     923           0 :                                 return false;
     924      567793 :                         break;
     925             :                 default:
     926           0 :                         assert(false);
     927             :                         break;
     928             :                 }
     929             : 
     930             :                 // the FMIref is created later
     931             :         }
     932             : 
     933       71580 :         for (DumpList<ForwardMethodType>::iterator it  = fwd.methodtypes.begin(),
     934       35790 :                                                        end = fwd.methodtypes.end(); it != end; ++it) {
     935           0 :                 Utf8String descriptor = (utf*) class_getconstant(c, it->descriptor_index, CONSTANT_Utf8);
     936             : 
     937           0 :                 if (descpool.add_method(descriptor) == -1)
     938           0 :                         return false;
     939             :         }
     940             : 
     941             :         // MethodHandles & InvokeDynamic are processed later
     942             : 
     943             :         /* everything was ok */
     944             : 
     945       35790 :         return true;
     946             : }
     947             : 
     948             : 
     949             : /* loader_load_attribute_signature *********************************************
     950             : 
     951             :    Signature_attribute {
     952             :        u2 attribute_name_index;
     953             :            u4 atrribute_length;
     954             :            u2 signature_index;
     955             :    }
     956             : 
     957             : *******************************************************************************/
     958             : 
     959             : #if defined(ENABLE_JAVASE)
     960       86570 : bool loader_load_attribute_signature(ClassBuffer& cb, Utf8String& signature)
     961             : {
     962             :         /* get classinfo */
     963             : 
     964       86570 :         classinfo *c = cb.get_class();
     965             : 
     966             :         /* destination must be NULL */
     967             : 
     968       86570 :         if (signature != NULL) {
     969           0 :                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
     970           0 :                 return false;
     971             :         }
     972             : 
     973             :         /* check remaining bytecode */
     974             : 
     975       86570 :         if (!cb.check_size(4 + 2))
     976           0 :                 return false;
     977             : 
     978             :         /* check attribute length */
     979             : 
     980       86570 :         u4 attribute_length = cb.read_u4();
     981             : 
     982       86570 :         if (attribute_length != 2) {
     983           0 :                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
     984           0 :                 return false;
     985             :         }
     986             : 
     987             :         /* get signature */
     988             : 
     989       86570 :         u2 signature_index = cb.read_u2();
     990             : 
     991       86570 :         signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
     992             : 
     993       86570 :         return signature != NULL;
     994             : }
     995             : #endif /* defined(ENABLE_JAVASE) */
     996             : 
     997             : 
     998             : /* load_class_from_sysloader ***************************************************
     999             : 
    1000             :    Load the class with the given name using the system class loader
    1001             : 
    1002             :    IN:
    1003             :        name.............the classname
    1004             : 
    1005             :    RETURN VALUE:
    1006             :        the loaded class, or
    1007             :            NULL if an exception has been thrown
    1008             : 
    1009             : *******************************************************************************/
    1010             : 
    1011             : #if defined(ENABLE_JAVASE)
    1012         141 : classinfo *load_class_from_sysloader(Utf8String name)
    1013             : {
    1014             :         classloader_t *cl;
    1015             :         classinfo     *c;
    1016             : 
    1017         141 :         cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
    1018             : 
    1019         141 :         if (cl == NULL)
    1020           0 :                 return NULL;
    1021             : 
    1022         141 :         c = load_class_from_classloader(name, cl);
    1023             : 
    1024         141 :         return c;
    1025             : }
    1026             : #endif /* defined(ENABLE_JAVASE) */
    1027             : 
    1028             : 
    1029             : // register loader real-time group
    1030             : RT_REGISTER_GROUP(linker_group,"linker","linker group")
    1031             : 
    1032             : // register real-time timers
    1033             : RT_REGISTER_GROUP_TIMER(checks_timer,"load","initial checks",linker_group)
    1034             : RT_REGISTER_GROUP_TIMER(ndpool_timer,"load","new descriptor pool",linker_group)
    1035             : RT_REGISTER_GROUP_TIMER(cpool_timer,"load","load constant pool",linker_group)
    1036             : RT_REGISTER_GROUP_TIMER(setup_timer,"load","class setup",linker_group)
    1037             : RT_REGISTER_GROUP_TIMER(fields_timer,"load","load fields",linker_group)
    1038             : RT_REGISTER_GROUP_TIMER(methods_timer,"load","load methods",linker_group)
    1039             : RT_REGISTER_GROUP_TIMER(classrefs_timer,"load","create classrefs",linker_group)
    1040             : RT_REGISTER_GROUP_TIMER(descs_timer,"load","allocate descriptors",linker_group)
    1041             : RT_REGISTER_GROUP_TIMER(setrefs_timer,"load","set classrefs",linker_group)
    1042             : RT_REGISTER_GROUP_TIMER(parsefds_timer,"load","parse field descriptors",linker_group)
    1043             : RT_REGISTER_GROUP_TIMER(parsemds_timer,"load","parse method descriptors",linker_group)
    1044             : RT_REGISTER_GROUP_TIMER(parsecpool_timer,"load","parse descriptors in constant pool",linker_group)
    1045             : RT_REGISTER_GROUP_TIMER(verify_timer,"load","verifier checks",linker_group)
    1046             : RT_REGISTER_GROUP_TIMER(attrs_timer,"load","load attributes",linker_group)
    1047             : 
    1048             : // register classloader real-time group
    1049             : RT_REGISTER_GROUP(cl_group,"classloader","classloader")
    1050             : 
    1051             : // register real-time timers
    1052             : RT_REGISTER_GROUP_TIMER(cllookup_timer,"classloader","lookup in classcache",cl_group)
    1053             : RT_REGISTER_GROUP_TIMER(prepare_timer,"classloader","prepare loader call",cl_group)
    1054             : RT_REGISTER_GROUP_TIMER(java_timer,"classloader","loader Java code",cl_group)
    1055             : RT_REGISTER_GROUP_TIMER(clcache_timer,"classloader","store in classcache",cl_group)
    1056             : 
    1057             : /* load_class_from_classloader *************************************************
    1058             : 
    1059             :    Load the class with the given name using the given user-defined class loader.
    1060             : 
    1061             :    IN:
    1062             :        name.............the classname
    1063             :            cl...............user-defined class loader
    1064             : 
    1065             :    RETURN VALUE:
    1066             :        the loaded class, or
    1067             :            NULL if an exception has been thrown
    1068             : 
    1069             : *******************************************************************************/
    1070             : 
    1071       38742 : classinfo *load_class_from_classloader(Utf8String name, classloader_t *cl)
    1072             : {
    1073             :         java_handle_t *o;
    1074             :         classinfo     *c;
    1075             :         classinfo     *tmpc;
    1076             :         java_handle_t *string;
    1077             : 
    1078             :         RT_TIMER_START(cllookup_timer);
    1079             : 
    1080       38742 :         assert(name);
    1081             : 
    1082             :         /* lookup if this class has already been loaded */
    1083             : 
    1084       38742 :         c = classcache_lookup(cl, name);
    1085             : 
    1086             :         RT_TIMER_STOPSTART(cllookup_timer,prepare_timer);
    1087             : 
    1088       38742 :         if (c != NULL)
    1089        8669 :                 return c;
    1090             : 
    1091             :         /* if other class loader than bootstrap, call it */
    1092             : 
    1093       30073 :         if (cl != NULL) {
    1094             :                 methodinfo *lc;
    1095             :                 const char *text;
    1096             :                 s4          namelen;
    1097             : 
    1098        1759 :                 text    = name.begin();
    1099        1759 :                 namelen = name.size();
    1100             : 
    1101             :                 /* handle array classes */
    1102        1759 :                 if (text[0] == '[') {
    1103             :                         classinfo *comp;
    1104         339 :                         Utf8String u;
    1105             : 
    1106         339 :                         switch (text[1]) {
    1107             :                         case 'L':
    1108             :                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
    1109           0 :                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
    1110           0 :                                         exceptions_throw_classnotfoundexception(name);
    1111           0 :                                         return NULL;
    1112             :                                 }
    1113             : 
    1114           0 :                                 u = Utf8String::from_utf8(text + 2, namelen - 3);
    1115             : 
    1116           0 :                                 if (!(comp = load_class_from_classloader(u, cl)))
    1117           0 :                                         return NULL;
    1118             : 
    1119             :                                 /* create the array class */
    1120             : 
    1121           0 :                                 c = class_array_of(comp, false);
    1122             : 
    1123           0 :                                 tmpc = classcache_store(cl, c, true);
    1124             : 
    1125           0 :                                 if (tmpc == NULL) {
    1126             :                                         /* exception, free the loaded class */
    1127           0 :                                         c->state &= ~CLASS_LOADING;
    1128           0 :                                         class_free(c);
    1129             :                                 }
    1130             : 
    1131           0 :                                 return tmpc;
    1132             : 
    1133             :                         case '[':
    1134             :                                 /* load the component class */
    1135             : 
    1136           0 :                                 u = Utf8String::from_utf8(text + 1, namelen - 1);
    1137             : 
    1138           0 :                                 if (!(comp = load_class_from_classloader(u, cl)))
    1139           0 :                                         return NULL;
    1140             : 
    1141             :                                 /* create the array class */
    1142             : 
    1143           0 :                                 c = class_array_of(comp, false);
    1144             : 
    1145           0 :                                 tmpc = classcache_store(cl, c, true);
    1146             : 
    1147           0 :                                 if (tmpc == NULL) {
    1148             :                                         /* exception, free the loaded class */
    1149           0 :                                         c->state &= ~CLASS_LOADING;
    1150           0 :                                         class_free(c);
    1151             :                                 }
    1152             : 
    1153           0 :                                 return tmpc;
    1154             : 
    1155             :                         default:
    1156             :                                 /* primitive array classes are loaded by the bootstrap loader */
    1157             : 
    1158         339 :                                 c = load_class_bootstrap(name);
    1159             : 
    1160         339 :                                 return c;
    1161             :                         }
    1162             :                 }
    1163             : 
    1164        1420 :                 LLNI_class_get(cl, c);
    1165             : 
    1166             : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
    1167             :                 /* OpenJDK uses this internal function because it's
    1168             :                    synchronized. */
    1169             : 
    1170             :                 lc = class_resolveclassmethod(c,
    1171             :                                                                           utf8::loadClassInternal,
    1172             :                                                                           utf8::java_lang_String__java_lang_Class,
    1173             :                                                                           NULL,
    1174             :                                                                           true);
    1175             : #else
    1176             :                 lc = class_resolveclassmethod(c,
    1177             :                                                                           utf8::loadClass,
    1178             :                                                                           utf8::java_lang_String__java_lang_Class,
    1179             :                                                                           NULL,
    1180        1420 :                                                                           true);
    1181             : #endif
    1182             : 
    1183        1420 :                 if (lc == NULL)
    1184           0 :                         return NULL; /* exception */
    1185             : 
    1186             :                 /* move return value into `o' and cast it afterwards to a classinfo* */
    1187             : 
    1188        1420 :                 string = JavaString::from_utf8_slash_to_dot(name);
    1189             : 
    1190             :                 RT_TIMER_STOPSTART(prepare_timer,java_timer);
    1191             : 
    1192        1420 :                 o = vm_call_method(lc, (java_handle_t *) cl, string);
    1193             : 
    1194             :                 RT_TIMER_STOPSTART(java_timer,clcache_timer);
    1195             : 
    1196        1420 :                 c = LLNI_classinfo_unwrap(o);
    1197             : 
    1198        1420 :                 if (c != NULL) {
    1199             :                         /* Store this class in the loaded class cache. If another
    1200             :                            class with the same (initloader,name) pair has been
    1201             :                            stored earlier it will be returned by classcache_store
    1202             :                            In this case classcache_store may not free the class
    1203             :                            because it has already been exposed to Java code which
    1204             :                            may have kept references to that class. */
    1205             : 
    1206        1389 :                     tmpc = classcache_store(cl, c, false);
    1207             : 
    1208        1389 :                         if (tmpc == NULL) {
    1209             :                                 /* exception, free the loaded class */
    1210           0 :                                 c->state &= ~CLASS_LOADING;
    1211           0 :                                 class_free(c);
    1212             :                         }
    1213             : 
    1214        1389 :                         c = tmpc;
    1215             :                 }
    1216             :                 else {
    1217             :                         // Expected behavior for the classloader is to throw an exception
    1218             :                         // and never return NULL. If the classloader shows a different
    1219             :                         // behavior, we are correcting it here (see PR126).
    1220          31 :                         if (exceptions_get_exception() == NULL) {
    1221             : #if !defined(NDEBUG)
    1222           0 :                                 if (opt_PrintWarnings)
    1223           0 :                                         log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
    1224             : #endif
    1225           0 :                                 exceptions_throw_classnotfoundexception(name);
    1226             :                         }
    1227             :                 }
    1228             : 
    1229             :                 RT_TIMER_STOP(clcache_timer);
    1230             : 
    1231             : 
    1232             :                 /* SUN compatible -verbose:class output */
    1233             : 
    1234        1420 :                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
    1235           0 :                         printf("[Loaded ");
    1236           0 :                         utf_display_printable_ascii_classname(name);
    1237           0 :                         printf("]\n");
    1238             :                 }
    1239             : 
    1240        1420 :                 return c;
    1241             :         }
    1242             : 
    1243       28314 :         c = load_class_bootstrap(name);
    1244             : 
    1245       28314 :         return c;
    1246             : }
    1247             : 
    1248             : 
    1249             : // register boot real-time group
    1250             : RT_REGISTER_GROUP(boot_group,"boot","boot group")
    1251             : 
    1252             : // register real-time timers
    1253             : RT_REGISTER_GROUP_TIMER(lookup_timer,"boot","lookup in classcache",boot_group)
    1254             : RT_REGISTER_GROUP_TIMER(array_timer,"boot","load array classes",boot_group)
    1255             : RT_REGISTER_GROUP_TIMER(suck_timer,"boot","suck class files",boot_group)
    1256             : RT_REGISTER_GROUP_TIMER(load_timer,"boot","load from class buffer",boot_group)
    1257             : RT_REGISTER_GROUP_TIMER(cache_timer,"boot","store in classcache",boot_group)
    1258             : 
    1259             : /* load_class_bootstrap ********************************************************
    1260             : 
    1261             :    Load the class with the given name using the bootstrap class loader.
    1262             : 
    1263             :    IN:
    1264             :        name.............the classname
    1265             : 
    1266             :    RETURN VALUE:
    1267             :        loaded classinfo, or
    1268             :            NULL if an exception has been thrown
    1269             : 
    1270             :    SYNCHRONIZATION:
    1271             :        load_class_bootstrap is synchronized. It can be treated as an
    1272             :            atomic operation.
    1273             : 
    1274             : *******************************************************************************/
    1275             : 
    1276       59438 : classinfo *load_class_bootstrap(Utf8String name)
    1277             : {
    1278             :         classinfo   *c;
    1279             :         classinfo   *r;
    1280             : 
    1281             :         RT_TIMER_START(lookup_timer);
    1282             : 
    1283             :         /* for debugging */
    1284             : 
    1285       59438 :         assert(name);
    1286             : 
    1287             :         /* lookup if this class has already been loaded */
    1288             : 
    1289       59438 :         r = classcache_lookup(NULL, name);
    1290             : 
    1291       59438 :         if (r != NULL) {
    1292             :                 RT_TIMER_STOP(lookup_timer);
    1293             : 
    1294       23360 :                 return r;
    1295             :         }
    1296             : 
    1297             :         RT_TIMER_STOP(lookup_timer);
    1298             : 
    1299             :         /* create the classinfo */
    1300             : 
    1301       36078 :         c = class_create_classinfo(name);
    1302             : 
    1303             :         /* handle array classes */
    1304             : 
    1305       36078 :         if (name[0] == '[') {
    1306         163 :                 c = load_newly_created_array(c, NULL);
    1307             :                 RT_TIMER_START(array_timer);
    1308             : 
    1309         163 :                 if (c == NULL)
    1310           0 :                         return NULL;
    1311             : 
    1312         163 :                 assert(c->state & CLASS_LOADED);
    1313             : 
    1314             :                 RT_TIMER_STOP(array_timer);
    1315             : 
    1316         163 :                 return c;
    1317             :         }
    1318             :         RT_TIMER_START(suck_timer);
    1319             : 
    1320             : #if defined(ENABLE_STATISTICS)
    1321             :         /* measure time */
    1322             : 
    1323             :         if (opt_getcompilingtime)
    1324             :                 compilingtime_stop();
    1325             : 
    1326             :         if (opt_getloadingtime)
    1327             :                 loadingtime_start();
    1328             : #endif
    1329             : 
    1330             :         /* load classdata, throw exception on error */
    1331             : 
    1332       35915 :         ClassBuffer cb(c);
    1333             : 
    1334       35915 :         if (!cb) {
    1335         769 :                 exceptions_throw_classnotfoundexception(name);
    1336         769 :                 return NULL;
    1337             :         }
    1338             : 
    1339             :         RT_TIMER_STOPSTART(suck_timer,load_timer);
    1340             : 
    1341             :         /* load the class from the buffer */
    1342             : 
    1343       35146 :         r = load_class_from_classbuffer(cb);
    1344             : 
    1345             :         RT_TIMER_STOPSTART(load_timer,cache_timer);
    1346             : 
    1347       35146 :         if (r == NULL) {
    1348             :                 /* the class could not be loaded, free the classinfo struct */
    1349             : 
    1350           0 :                 class_free(c);
    1351             :         }
    1352             :         else {
    1353             :                 /* Store this class in the loaded class cache this step also
    1354             :                    checks the loading constraints. If the class has been
    1355             :                    loaded before, the earlier loaded class is returned. */
    1356             : 
    1357       35146 :                 classinfo *res = classcache_store(NULL, c, true);
    1358             : 
    1359       35146 :                 if (res == NULL) {
    1360             :                         /* exception */
    1361           0 :                         class_free(c);
    1362             :                 }
    1363             :                 else {
    1364             :                         // Add the package name to the boot packages.
    1365       35146 :                         Package::add(c->packagename);
    1366             :                 }
    1367             : 
    1368       35146 :                 r = res;
    1369             :         }
    1370             : 
    1371             :         RT_TIMER_STOP(cache_timer);
    1372             : 
    1373             :         /* SUN compatible -verbose:class output */
    1374             : 
    1375       35146 :         if (opt_verboseclass && r) {
    1376           0 :                 printf("[Loaded ");
    1377           0 :                 utf_display_printable_ascii_classname(name);
    1378           0 :                 printf(" from %s]\n", cb.get_path());
    1379             :         }
    1380             : 
    1381             :         /* free memory */
    1382             : 
    1383       35146 :         cb.free();
    1384             : 
    1385             : #if defined(ENABLE_STATISTICS)
    1386             :         /* measure time */
    1387             : 
    1388             :         if (opt_getloadingtime)
    1389             :                 loadingtime_stop();
    1390             : 
    1391             :         if (opt_getcompilingtime)
    1392             :                 compilingtime_start();
    1393             : #endif
    1394             : 
    1395       35146 :         return r;
    1396             : }
    1397             : 
    1398             : 
    1399             : /* load_class_from_classbuffer_intern ******************************************
    1400             : 
    1401             :    Loads a class from a classbuffer into a given classinfo structure.
    1402             :    Super-classes are also loaded at this point and some verfication
    1403             :    checks are done.
    1404             : 
    1405             :    SYNCHRONIZATION:
    1406             :        This function is NOT synchronized!
    1407             : 
    1408             : *******************************************************************************/
    1409             : 
    1410       35790 : static bool load_class_from_classbuffer_intern(ClassBuffer& cb)
    1411             : {
    1412             :         // Create new dump memory area.
    1413       35790 :         DumpMemoryArea dma;
    1414             : 
    1415             :         RT_TIMER_START(checks_timer);
    1416             : 
    1417             :         /* Get the classbuffer's class. */
    1418             : 
    1419       35790 :         classinfo *c = cb.get_class();
    1420             : 
    1421       35790 :         if (!cb.check_size(4 + 2 + 2))
    1422           0 :                 return false;
    1423             : 
    1424             :         /* check signature */
    1425             : 
    1426       35790 :         if (cb.read_u4() != MAGIC) {
    1427           0 :                 exceptions_throw_classformaterror(c, "Bad magic number");
    1428           0 :                 return false;
    1429             :         }
    1430             : 
    1431             :         /* check version */
    1432             : 
    1433       35790 :         u4 mi = cb.read_u2();
    1434       35790 :         u4 ma = cb.read_u2();
    1435       35790 :         c->version = ClassFileVersion(ma, mi);
    1436             : 
    1437       35790 :         if (ClassFileVersion::CACAO_VERSION < c->version) {
    1438           0 :                 exceptions_throw_unsupportedclassversionerror(c);
    1439           0 :                 return false;
    1440             :         }
    1441             : 
    1442             : 
    1443             :         RT_TIMER_STOPSTART(checks_timer,ndpool_timer);
    1444             : 
    1445             :         /* create a new descriptor pool */
    1446             : 
    1447       35790 :         DescriptorPool descpool(c);
    1448             : 
    1449             :         RT_TIMER_STOPSTART(ndpool_timer,cpool_timer);
    1450             : 
    1451             :         /* load the constant pool */
    1452             : 
    1453       35790 :         ForwardReferences fwd;
    1454             : 
    1455       35790 :         if (!load_constantpool(cb, fwd, descpool))
    1456           0 :                 return false;
    1457             : 
    1458             :         RT_TIMER_STOPSTART(cpool_timer,setup_timer);
    1459             : 
    1460             :         /* ACC flags */
    1461             : 
    1462       35790 :         if (!cb.check_size(2))
    1463           0 :                 return false;
    1464             : 
    1465             :         /* We OR the flags here, as we set already some flags in
    1466             :            class_create_classinfo. */
    1467             : 
    1468       35790 :         c->flags |= cb.read_u2();
    1469             : 
    1470             :         /* check ACC flags consistency */
    1471             : 
    1472       35790 :         if (c->flags & ACC_INTERFACE) {
    1473        6012 :                 if (!(c->flags & ACC_ABSTRACT)) {
    1474             :                         /* We work around this because interfaces in JDK 1.1 are
    1475             :                          * not declared abstract. */
    1476             : 
    1477           0 :                         c->flags |= ACC_ABSTRACT;
    1478             :                 }
    1479             : 
    1480        6012 :                 if (c->flags & ACC_FINAL) {
    1481             :                         exceptions_throw_classformaterror(c,
    1482             :                                                                                           "Illegal class modifiers: 0x%X",
    1483           0 :                                                                                           c->flags);
    1484           0 :                         return false;
    1485             :                 }
    1486             : 
    1487        6012 :                 if (c->flags & ACC_SUPER) {
    1488           0 :                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
    1489             :                 }
    1490             :         }
    1491             : 
    1492       35790 :         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
    1493             :                 exceptions_throw_classformaterror(c,
    1494             :                                                                                   "Illegal class modifiers: 0x%X",
    1495           0 :                                                                                   c->flags);
    1496           0 :                 return false;
    1497             :         }
    1498             : 
    1499       35790 :         if (!cb.check_size(2 + 2))
    1500           0 :                 return false;
    1501             : 
    1502             :         /* This class. */
    1503             : 
    1504       35790 :         uint16_t index = cb.read_u2();
    1505             : 
    1506       35790 :         Utf8String name = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
    1507             : 
    1508       35790 :         if (name == NULL)
    1509           0 :                 return false;
    1510             : 
    1511       35790 :         if (c->name == utf8::not_named_yet) {
    1512             :                 /* we finally have a name for this class */
    1513           2 :                 c->name = name;
    1514           2 :                 class_set_packagename(c);
    1515             :         }
    1516       35788 :         else if (name != c->name) {
    1517           0 :                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
    1518           0 :                 return false;
    1519             :         }
    1520             : 
    1521             :         /* Retrieve superclass. */
    1522             : 
    1523       35790 :         c->super = NULL;
    1524             : 
    1525       35790 :         index = cb.read_u2();
    1526             : 
    1527       35790 :         Utf8String supername;
    1528             : 
    1529       35790 :         if (index == 0) {
    1530         163 :                 supername = NULL;
    1531             : 
    1532             :                 /* This is only allowed for java.lang.Object. */
    1533             : 
    1534         163 :                 if (c->name != utf8::java_lang_Object) {
    1535           0 :                         exceptions_throw_classformaterror(c, "Bad superclass index");
    1536           0 :                         return false;
    1537             :                 }
    1538             :         }
    1539             :         else {
    1540       35627 :                 supername = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
    1541             : 
    1542       35627 :                 if (supername == NULL)
    1543           0 :                         return false;
    1544             : 
    1545             :                 /* java.lang.Object may not have a super class. */
    1546             : 
    1547       35627 :                 if (c->name == utf8::java_lang_Object) {
    1548           0 :                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
    1549           0 :                         return false;
    1550             :                 }
    1551             : 
    1552             :                 /* Detect circularity. */
    1553             : 
    1554       35627 :                 if (supername == c->name) {
    1555           0 :                         exceptions_throw_classcircularityerror(c);
    1556           0 :                         return false;
    1557             :                 }
    1558             : 
    1559             :                 /* Interfaces must have java.lang.Object as super class. */
    1560             : 
    1561       35627 :                 if ((c->flags & ACC_INTERFACE) && (supername != utf8::java_lang_Object)) {
    1562           0 :                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
    1563           0 :                         return false;
    1564             :                 }
    1565             :         }
    1566             : 
    1567             :         /* Parse the super interfaces. */
    1568             : 
    1569       35790 :         if (!cb.check_size(2))
    1570           0 :                 return false;
    1571             : 
    1572       35790 :         c->interfacescount = cb.read_u2();
    1573             : 
    1574       35790 :         if (!cb.check_size(2 * c->interfacescount))
    1575           0 :                 return false;
    1576             : 
    1577       35790 :         c->interfaces = MNEW(classinfo*, c->interfacescount);
    1578             : 
    1579             :         /* Get the names of the super interfaces. */
    1580             : 
    1581       35790 :         Utf8String *interfacesnames = (Utf8String*) DumpMemory::allocate(sizeof(Utf8String) * c->interfacescount);
    1582             : 
    1583       56229 :         for (int32_t i = 0; i < c->interfacescount; i++) {
    1584       20439 :                 uint16_t index = cb.read_u2();
    1585             : 
    1586       20439 :                 Utf8String u = (utf *) class_getconstant(c, index, CONSTANT_ClassName);
    1587             : 
    1588       20439 :                 if (u == NULL)
    1589           0 :                         return false;
    1590             : 
    1591       20439 :                 interfacesnames[i] = u;
    1592             :         }
    1593             : 
    1594             :         RT_TIMER_STOPSTART(setup_timer,fields_timer);
    1595             : 
    1596             :         /* Parse fields. */
    1597             : 
    1598       35790 :         if (!cb.check_size(2))
    1599           0 :                 return false;
    1600             : 
    1601       35790 :         c->fieldscount = cb.read_u2();
    1602       35790 :         c->fields      = MNEW(fieldinfo, c->fieldscount);
    1603             : 
    1604       35790 :         MZERO(c->fields, fieldinfo, c->fieldscount);
    1605             : 
    1606      149158 :         for (int32_t i = 0; i < c->fieldscount; i++) {
    1607      113368 :                 if (!field_load(cb, &(c->fields[i]), descpool))
    1608           0 :                         return false;
    1609             :         }
    1610             : 
    1611             :         RT_TIMER_STOPSTART(fields_timer,methods_timer);
    1612             : 
    1613             :         /* Parse methods. */
    1614             : 
    1615       35790 :         if (!cb.check_size(2))
    1616           0 :                 return false;
    1617             : 
    1618       35790 :         c->methodscount = cb.read_u2();
    1619       35790 :         c->methods      = MNEW(methodinfo, c->methodscount);
    1620             : 
    1621       35790 :         MZERO(c->methods, methodinfo, c->methodscount);
    1622             : 
    1623      505718 :         for (int32_t i = 0; i < c->methodscount; i++) {
    1624      469928 :                 if (!method_load(cb, &(c->methods[i]), descpool))
    1625           0 :                         return false;
    1626             :         }
    1627             : 
    1628             :         RT_TIMER_STOPSTART(methods_timer,classrefs_timer);
    1629             : 
    1630             :         /* create the class reference table */
    1631             : 
    1632       35790 :         c->classrefs = descpool.create_classrefs(&(c->classrefcount));
    1633             : 
    1634             :         RT_TIMER_STOPSTART(classrefs_timer,descs_timer);
    1635             : 
    1636             :         /* allocate space for the parsed descriptors */
    1637             : 
    1638       35790 :         descpool.alloc_parsed_descriptors();
    1639             : 
    1640             : #if defined(ENABLE_STATISTICS)
    1641             :         size_t classrefsize, descsize;
    1642             : 
    1643             :         descpool.get_sizes(&classrefsize, &descsize);
    1644             :         count_classref_len    += classrefsize;
    1645             :         count_parsed_desc_len += descsize;
    1646             : #endif
    1647             : 
    1648             :         RT_TIMER_STOPSTART(descs_timer,setrefs_timer);
    1649             : 
    1650             :         // put the classrefs in the constant pool
    1651             : 
    1652      409198 :         for (DumpList<ForwardClass>::iterator it  = fwd.classes.begin(),
    1653       35790 :                                               end = fwd.classes.end(); it != end; ++it) {
    1654      337618 :                 Utf8String name = (utf*) class_getconstant(c, it->this_index, CONSTANT_ClassName);
    1655             : 
    1656      337618 :                 c->cptags[it->this_index]  = CONSTANT_Class;
    1657      337618 :                 c->cpinfos[it->this_index] = descpool.lookup_classref(name);
    1658             :         }
    1659             : 
    1660             :         // get parsed descriptors for MethodTypes & InvokeDynamic call sites
    1661             : 
    1662       71580 :         for (DumpList<ForwardMethodType>::iterator it  = fwd.methodtypes.begin(),
    1663       35790 :                                                        end = fwd.methodtypes.end(); it != end; ++it) {
    1664           0 :                 Utf8String  descriptor = (utf*) class_getconstant(c, it->descriptor_index, CONSTANT_Utf8);
    1665           0 :                 methoddesc *parseddesc = descpool.parse_method_descriptor(descriptor, ACC_STATIC, NULL);
    1666             : 
    1667           0 :                 c->cptags[it->this_index]  = CONSTANT_MethodType;
    1668           0 :                 c->cpinfos[it->this_index] = new (ConstantPool) constant_MethodType(descriptor, parseddesc);
    1669             :         }
    1670             : 
    1671       71580 :         for (DumpList<ForwardInvokeDynamic>::iterator it  = fwd.invokedynamics.begin(),
    1672       35790 :                                                           end = fwd.invokedynamics.end(); it != end; ++it) {
    1673           0 :                 constant_nameandtype *nat = (constant_nameandtype*) class_getconstant(c, it->name_and_type_index, CONSTANT_NameAndType);
    1674             : 
    1675           0 :                 Utf8String name = nat->name;
    1676           0 :                 Utf8String desc = nat->descriptor;
    1677             : 
    1678           0 :                 methoddesc *md = descpool.parse_method_descriptor(desc, ACC_STATIC, NULL);
    1679           0 :                 md->params_from_paramtypes(ACC_STATIC);
    1680             : 
    1681           0 :                 c->cptags[it->this_index]  = CONSTANT_InvokeDynamic;
    1682           0 :                 c->cpinfos[it->this_index] = new (ConstantPool) constant_InvokeDynamic(it->bootstrap_method_attr_index, name, desc, md);
    1683             :         }
    1684             : 
    1685             :         /* Resolve the super class. */
    1686             : 
    1687       35790 :         if (supername != NULL) {
    1688       35627 :                 constant_classref *cr = descpool.lookup_classref(supername);
    1689             : 
    1690       35627 :                 if (cr == NULL)
    1691           0 :                         return false;
    1692             : 
    1693             :                 /* XXX This should be done better. */
    1694       35627 :                 classinfo *tc = resolve_classref_or_classinfo_eager(to_classref_or_classinfo(cr), false);
    1695             : 
    1696       35627 :                 if (tc == NULL) {
    1697           1 :                         resolve_handle_pending_exception(true);
    1698           1 :                         return false;
    1699             :                 }
    1700             : 
    1701             :                 /* Interfaces are not allowed as super classes. */
    1702             : 
    1703       35626 :                 if (tc->flags & ACC_INTERFACE) {
    1704           0 :                         exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
    1705           0 :                         return false;
    1706             :                 }
    1707             : 
    1708             :                 /* Don't allow extending final classes */
    1709             : 
    1710       35626 :                 if (tc->flags & ACC_FINAL) {
    1711           0 :                         exceptions_throw_verifyerror(NULL, "Cannot inherit from final class");
    1712           0 :                         return false;
    1713             :                 }
    1714             : 
    1715             :                 /* Store the super class. */
    1716             : 
    1717       35626 :                 c->super = tc;
    1718             :         }
    1719             : 
    1720             :         /* Resolve the super interfaces. */
    1721             : 
    1722       56227 :         for (int32_t i = 0; i < c->interfacescount; i++) {
    1723       20439 :                 Utf8String         u  = interfacesnames[i];
    1724       20439 :                 constant_classref *cr = descpool.lookup_classref(u);
    1725             : 
    1726       20439 :                 if (cr == NULL)
    1727           0 :                         return false;
    1728             : 
    1729             :                 /* XXX This should be done better. */
    1730       20439 :                 classinfo *tc = resolve_classref_or_classinfo_eager(to_classref_or_classinfo(cr), false);
    1731             : 
    1732       20439 :                 if (tc == NULL) {
    1733           1 :                         resolve_handle_pending_exception(true);
    1734           1 :                         return false;
    1735             :                 }
    1736             : 
    1737             :                 /* Detect circularity. */
    1738             : 
    1739       20438 :                 if (tc == c) {
    1740           0 :                         exceptions_throw_classcircularityerror(c);
    1741           0 :                         return false;
    1742             :                 }
    1743             : 
    1744       20438 :                 if (!(tc->flags & ACC_INTERFACE)) {
    1745           0 :                         exceptions_throw_incompatibleclasschangeerror(tc, "Implementing class");
    1746           0 :                         return false;
    1747             :                 }
    1748             : 
    1749             :                 /* Store the super interface. */
    1750             : 
    1751       20438 :                 c->interfaces[i] = tc;
    1752             :         }
    1753             : 
    1754             :         RT_TIMER_STOPSTART(setrefs_timer,parsefds_timer);
    1755             : 
    1756             :         /* Parse the field descriptors. */
    1757             : 
    1758      149154 :         for (int32_t i = 0; i < c->fieldscount; i++) {
    1759      113366 :                 c->fields[i].parseddesc = descpool.parse_field_descriptor(c->fields[i].descriptor);
    1760      113366 :                 if (!c->fields[i].parseddesc)
    1761           0 :                         return false;
    1762             :         }
    1763             : 
    1764             :         RT_TIMER_STOPSTART(parsefds_timer,parsemds_timer);
    1765             : 
    1766             :         /* parse method descriptors */
    1767             : 
    1768      505714 :         for (int32_t i = 0; i < c->methodscount; i++) {
    1769      469926 :                 methodinfo *m = &c->methods[i];
    1770      469926 :                 m->parseddesc = descpool.parse_method_descriptor(m->descriptor, m->flags, class_get_self_classref(m->clazz));
    1771      469926 :                 if (!m->parseddesc)
    1772           0 :                         return false;
    1773             : 
    1774      513109 :                 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
    1775       43183 :                         if (!m->rawexceptiontable[j].catchtype.any)
    1776       20709 :                                 continue;
    1777             : 
    1778       44948 :                         if ((m->rawexceptiontable[j].catchtype.ref =
    1779       22474 :                                 descpool.lookup_classref((utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
    1780           0 :                                 return false;
    1781             :                 }
    1782             : 
    1783      532490 :                 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
    1784       62564 :                         if (!m->thrownexceptions[j].any)
    1785           0 :                                 continue;
    1786             : 
    1787      125128 :                         if ((m->thrownexceptions[j].ref =
    1788       62564 :                                 descpool.lookup_classref((utf *) m->thrownexceptions[j].any)) == NULL)
    1789           0 :                                 return false;
    1790             :                 }
    1791             :         }
    1792             : 
    1793             :         RT_TIMER_STOPSTART(parsemds_timer,parsecpool_timer);
    1794             : 
    1795             :         /* parse the loaded descriptors */
    1796             : 
    1797      740304 :         for (DumpList<ForwardFieldMethInt>::iterator it  = fwd.fieldmethints.begin(),
    1798       35788 :                                                      end = fwd.fieldmethints.end(); it != end; ++it) {
    1799      668728 :                 constant_nameandtype *nat = (constant_nameandtype*) class_getconstant(c, it->nameandtype_index, CONSTANT_NameAndType);
    1800             : 
    1801      668728 :                 Utf8String name       = nat->name;
    1802      668728 :                 Utf8String descriptor = nat->descriptor;
    1803             : 
    1804      668728 :                 constant_classref *classref = (constant_classref *) class_getconstant(c, it->class_index, CONSTANT_Class);
    1805      668728 :                 if (!classref)
    1806           0 :                         return false;
    1807             : 
    1808             :                 parseddesc_t parseddesc;
    1809             : 
    1810      668728 :                 switch (it->tag) {
    1811             :                 case CONSTANT_Fieldref: {
    1812      100937 :                         parseddesc.fd = descpool.parse_field_descriptor(descriptor);
    1813      100937 :                         if (!parseddesc)
    1814           0 :                                 return false;
    1815      100937 :                         break;
    1816             :                 }
    1817             : 
    1818             :                 case CONSTANT_Methodref:
    1819             :                 case CONSTANT_InterfaceMethodref: {
    1820      567791 :                         parseddesc.md = descpool.parse_method_descriptor(descriptor, ACC_UNDEF, classref);
    1821      567791 :                         if (!parseddesc)
    1822           0 :                                 return false;
    1823      567791 :                         break;
    1824             :                 }
    1825             :                 default:
    1826           0 :                         assert(false);
    1827             :                 }
    1828             : 
    1829      668728 :                 c->cptags[it->this_index]  = it->tag;
    1830      668728 :                 c->cpinfos[it->this_index] = new (ConstantPool) constant_FMIref(classref, name, descriptor, parseddesc);
    1831             :         }
    1832             : 
    1833       71576 :         for (DumpList<ForwardMethodHandle>::iterator it  = fwd.methodhandles.begin(),
    1834       35788 :                                                          end = fwd.methodhandles.end(); it != end; ++it) {
    1835           0 :                 MethodHandleKind kind = (MethodHandleKind) it->reference_kind;
    1836             : 
    1837             :                 constant_FMIref *fmi;
    1838             : 
    1839           0 :                 switch (kind) {
    1840             :                 case REF_getField:
    1841             :                 case REF_getStatic:
    1842             :                 case REF_putField:
    1843             :                 case REF_putStatic:
    1844           0 :                         fmi  = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Fieldref);
    1845             : 
    1846           0 :                         if (!fmi)
    1847           0 :                                 return false;
    1848           0 :                         break;
    1849             : 
    1850             :                 case REF_invokeVirtual:
    1851             :                 case REF_invokeStatic:
    1852             :                 case REF_invokeSpecial:
    1853           0 :                         fmi  = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Methodref);
    1854             : 
    1855           0 :                         if (!fmi)
    1856           0 :                                 return false;
    1857             : 
    1858           0 :                         if (fmi->name == utf8::init || fmi->name == utf8::clinit) {
    1859           0 :                                 exceptions_throw_classformaterror(c, "Illegal method handle");
    1860           0 :                                 return false;
    1861             :                         }
    1862           0 :                         break;
    1863             :                         
    1864             :                 case REF_newInvokeSpecial:
    1865           0 :                         fmi  = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_Methodref);
    1866             : 
    1867           0 :                         if (!fmi)
    1868           0 :                                 return false;
    1869             : 
    1870           0 :                         if (fmi->name != utf8::init) {
    1871           0 :                                 exceptions_throw_classformaterror(c, "Illegal method handle");
    1872           0 :                                 return false;
    1873             :                         }
    1874           0 :                         break;
    1875             :                                 
    1876             :                 case REF_invokeInterface:
    1877           0 :                         fmi  = (constant_FMIref*) class_getconstant(c, it->reference_index, CONSTANT_InterfaceMethodref);
    1878             : 
    1879           0 :                         if (!fmi)
    1880           0 :                                 return false;
    1881             : 
    1882           0 :                         if (fmi->name == utf8::init || fmi->name == utf8::clinit) {
    1883           0 :                                 exceptions_throw_classformaterror(c, "Illegal method handle");
    1884           0 :                                 return false;
    1885             :                         }
    1886           0 :                         break;
    1887             : 
    1888             :                 default:
    1889           0 :                         exceptions_throw_classformaterror(c, "Illegal reference kind in method handle");
    1890           0 :                         return false;
    1891             :                 }
    1892             : 
    1893           0 :                 c->cptags[it->this_index]  = CONSTANT_MethodHandle;
    1894           0 :                 c->cpinfos[it->this_index] = new (ConstantPool) constant_MethodHandle(kind, fmi);
    1895             :         }
    1896             : 
    1897             :         RT_TIMER_STOPSTART(parsecpool_timer,verify_timer);
    1898             : 
    1899             : #ifdef ENABLE_VERIFIER
    1900             :         /* Check if all fields and methods can be uniquely
    1901             :          * identified by (name,descriptor). */
    1902             : 
    1903       35788 :         if (opt_verify) {
    1904             :                 /* We use a hash table here to avoid making the
    1905             :                  * average case quadratic in # of methods, fields.
    1906             :                  */
    1907             :                 static int shift = 0;
    1908             :                 u2 *hashtab;
    1909             :                 u2 *next; /* for chaining colliding hash entries */
    1910             :                 int32_t len;
    1911             :                 int32_t hashlen;
    1912             :                 u2 index;
    1913             :                 u2 old;
    1914             : 
    1915             :                 /* Allocate hashtable */
    1916       35788 :                 len = c->methodscount;
    1917       35788 :                 if (len < c->fieldscount) len = c->fieldscount;
    1918       35788 :                 hashlen = 5 * len;
    1919       35788 :                 hashtab = MNEW(u2,(hashlen + len));
    1920       35788 :                 next = hashtab + hashlen;
    1921             : 
    1922             :                 /* Determine bitshift (to get good hash values) */
    1923       35788 :                 if (!shift) {
    1924         163 :                         len = Utf8String::sizeof_utf;
    1925        1304 :                         while (len) {
    1926         978 :                                 len >>= 1;
    1927         978 :                                 shift++;
    1928             :                         }
    1929             :                 }
    1930             : 
    1931             :                 /* Check fields */
    1932       35788 :                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
    1933             : 
    1934      149154 :                 for (int32_t i = 0; i < c->fieldscount; ++i) {
    1935      113366 :                         fieldinfo *fi = c->fields + i;
    1936             : 
    1937             :                         /* It's ok if we lose bits here */
    1938             :                         index = ((((size_t) fi->name.c_ptr()) +
    1939      113366 :                                           ((size_t) fi->descriptor.c_ptr())) >> shift) % hashlen;
    1940             : 
    1941      113366 :                         if ((old = hashtab[index])) {
    1942        8449 :                                 old--;
    1943        8449 :                                 next[i] = old;
    1944        9115 :                                 do {
    1945        9115 :                                         if (c->fields[old].name == fi->name &&
    1946           0 :                                                 c->fields[old].descriptor == fi->descriptor) {
    1947           0 :                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
    1948           0 :                                                 return false;
    1949             :                                         }
    1950        9115 :                                 } while ((old = next[old]));
    1951             :                         }
    1952      113366 :                         hashtab[index] = i + 1;
    1953             :                 }
    1954             : 
    1955             :                 /* Check methods */
    1956       35788 :                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
    1957             : 
    1958      505714 :                 for (int32_t i = 0; i < c->methodscount; ++i) {
    1959      469926 :                         methodinfo *mi = c->methods + i;
    1960             : 
    1961             :                         /* It's ok if we lose bits here */
    1962             :                         index = ((((size_t) mi->name.c_ptr()) +
    1963      469926 :                                           ((size_t) mi->descriptor.c_ptr())) >> shift) % hashlen;
    1964             : 
    1965      469926 :                         if ((old = hashtab[index])) {
    1966       46644 :                                 old--;
    1967       46644 :                                 next[i] = old;
    1968       50310 :                                 do {
    1969       52898 :                                         if (c->methods[old].name == mi->name &&
    1970        2588 :                                                 c->methods[old].descriptor == mi->descriptor) {
    1971           0 :                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
    1972           0 :                                                 return false;
    1973             :                                         }
    1974       50310 :                                 } while ((old = next[old]));
    1975             :                         }
    1976      469926 :                         hashtab[index] = i + 1;
    1977             :                 }
    1978             : 
    1979       35788 :                 MFREE(hashtab, u2, (hashlen + len));
    1980             :         }
    1981             : #endif /* ENABLE_VERIFIER */
    1982             : 
    1983             :         RT_TIMER_STOPSTART(verify_timer,attrs_timer);
    1984             : 
    1985             :         STATISTICS(size_classinfo  += sizeof(classinfo*) * c->interfacescount);
    1986             :         STATISTICS(size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount);
    1987             :         STATISTICS(size_methodinfo += sizeof(methodinfo) * c->methodscount);
    1988             : 
    1989             :         /* load attribute structures */
    1990             : 
    1991       35788 :         if (!class_load_attributes(cb))
    1992           0 :                 return false;
    1993             : 
    1994             :         // Pre Java 1.5 version don't check this. This implementation is
    1995             :         // like Java 1.5 do it: for class file version 45.3 we don't check
    1996             :         // it, older versions are checked.
    1997             : 
    1998       35788 :         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
    1999             :                 // check if all data has been read
    2000       35788 :                 if (cb.remaining() != 0) {
    2001           0 :                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
    2002           0 :                         return false;
    2003             :                 }
    2004             :         }
    2005             : 
    2006             :         RT_TIMER_STOP(attrs_timer);
    2007             : 
    2008       35788 :         return true;
    2009             : }
    2010             : 
    2011             : 
    2012             : /* load_class_from_classbuffer *************************************************
    2013             : 
    2014             :    Convenience wrapper for load_class_from_classbuffer.
    2015             : 
    2016             :    SYNCHRONIZATION:
    2017             :        This function is NOT synchronized!
    2018             : 
    2019             : *******************************************************************************/
    2020             : 
    2021       35790 : classinfo *load_class_from_classbuffer(ClassBuffer& cb)
    2022             : {
    2023             :         classinfo *c;
    2024             :         bool       result;
    2025             : 
    2026             :         /* Get the classbuffer's class. */
    2027             : 
    2028       35790 :         c = cb.get_class();
    2029             : 
    2030             :         /* Check if the class is already loaded. */
    2031             : 
    2032       35790 :         if (c->state & CLASS_LOADED)
    2033           0 :                 return c;
    2034             : 
    2035             :         STATISTICS(count_class_loads++);
    2036             : 
    2037             : #if !defined(NDEBUG)
    2038       35790 :         if (loadverbose)
    2039           0 :                 log_message_class("Loading class: ", c);
    2040             : #endif
    2041             : 
    2042             :         /* Class is currently loading. */
    2043             : 
    2044       35790 :         c->state |= CLASS_LOADING;
    2045             : 
    2046             :         /* Parse the classbuffer. */
    2047             : 
    2048       35790 :         result = load_class_from_classbuffer_intern(cb);
    2049             : 
    2050             :         /* An error occurred. */
    2051             : 
    2052       35790 :         if (result == false) {
    2053             :                 /* Revert loading state. */
    2054             : 
    2055           2 :                 c->state = (c->state & ~CLASS_LOADING);
    2056             : 
    2057           2 :                 return NULL;
    2058             :         }
    2059             : 
    2060             :         /* Revert loading state and set loaded. */
    2061             : 
    2062       35788 :         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
    2063             : 
    2064             : #if !defined(NDEBUG)
    2065       35788 :         if (loadverbose)
    2066           0 :                 log_message_class("Loading done class: ", c);
    2067             : #endif
    2068             : 
    2069             :         // Hook point just after a class was loaded.
    2070       35788 :         Hook::class_loaded(c);
    2071             : 
    2072       35788 :         return c;
    2073             : }
    2074             : 
    2075             : 
    2076             : /* load_newly_created_array ****************************************************
    2077             : 
    2078             :    Load a newly created array class.
    2079             : 
    2080             :         RETURN VALUE:
    2081             :             c....................the array class C has been loaded
    2082             :                 other classinfo......the array class was found in the class cache,
    2083             :                                      C has been freed
    2084             :             NULL.................an exception has been thrown
    2085             : 
    2086             :         Note:
    2087             :                 This is an internal function. Do not use it unless you know exactly
    2088             :                 what you are doing!
    2089             : 
    2090             :                 Use one of the load_class_... functions for general array class loading.
    2091             : 
    2092             : *******************************************************************************/
    2093             : 
    2094        4944 : classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
    2095             : {
    2096        4944 :         classinfo         *comp = NULL;
    2097             :         methodinfo        *clone;
    2098             :         methoddesc        *clonedesc;
    2099             :         constant_classref *classrefs;
    2100             :         const char        *text;
    2101             :         s4                 namelen;
    2102        4944 :         Utf8String         u;
    2103             : 
    2104        4944 :         Utf8String name = c->name;
    2105             : 
    2106        4944 :         text    = name.begin();
    2107        4944 :         namelen = name.size();
    2108             : 
    2109             :         /* Check array class name */
    2110             : 
    2111        4944 :         if ((namelen < 2) || (text[0] != '[')) {
    2112           0 :                 exceptions_throw_classnotfoundexception(c->name);
    2113           0 :                 return NULL;
    2114             :         }
    2115             : 
    2116             :         /* Check the element type */
    2117             : 
    2118        4944 :         switch (text[1]) {
    2119             :         case '[':
    2120             :                 /* c is an array of arrays. We have to create the component class. */
    2121             : 
    2122         569 :                 comp = load_class_from_classloader(name.substring(1), loader);
    2123             : 
    2124         569 :                 if (comp == NULL)
    2125           0 :                         return NULL;
    2126             : 
    2127         569 :                 assert(comp->state & CLASS_LOADED);
    2128             : 
    2129             :                 /* the array's flags are that of the component class */
    2130         569 :                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
    2131         569 :                 c->classloader = comp->classloader;
    2132         569 :                 break;
    2133             : 
    2134             :         case 'L':
    2135             :                 /* c is an array of objects. */
    2136             : 
    2137             :                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
    2138        3071 :                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
    2139           0 :                         exceptions_throw_classnotfoundexception(c->name);
    2140           0 :                         return NULL;
    2141             :                 }
    2142             : 
    2143        3071 :                 u  = Utf8String::from_utf8(text + 2, namelen - 3);
    2144             : 
    2145        3071 :                 if (!(comp = load_class_from_classloader(u, loader)))
    2146           0 :                         return NULL;
    2147             : 
    2148        3071 :                 assert(comp->state & CLASS_LOADED);
    2149             : 
    2150             :                 /* the array's flags are that of the component class */
    2151        3071 :                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
    2152        3071 :                 c->classloader = comp->classloader;
    2153        3071 :                 break;
    2154             : 
    2155             :         default:
    2156             :                 /* c is an array of a primitive type */
    2157             : 
    2158             :                 /* check for cases like `[II' and whether the character is a
    2159             :                    valid primitive type */
    2160             : 
    2161        1304 :                 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
    2162           0 :                         exceptions_throw_classnotfoundexception(c->name);
    2163           0 :                         return NULL;
    2164             :                 }
    2165             : 
    2166             :                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
    2167        1304 :                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
    2168        1304 :                 c->classloader = NULL;
    2169             :         }
    2170             : 
    2171        4944 :         assert(class_java_lang_Object);
    2172             : #if defined(ENABLE_JAVASE)
    2173        4944 :         assert(class_java_lang_Cloneable);
    2174        4944 :         assert(class_java_io_Serializable);
    2175             : #endif
    2176             : 
    2177             :         /* Setup the array class. */
    2178             : 
    2179        4944 :         c->super = class_java_lang_Object;
    2180             : 
    2181             : #if defined(ENABLE_JAVASE)
    2182             : 
    2183        4944 :         c->interfacescount = 2;
    2184        4944 :     c->interfaces      = MNEW(classinfo*, 2);
    2185        4944 :         c->interfaces[0]   = class_java_lang_Cloneable;
    2186        4944 :         c->interfaces[1]   = class_java_io_Serializable;
    2187             : 
    2188             : #elif defined(ENABLE_JAVAME_CLDC1_1)
    2189             : 
    2190             :         c->interfacescount = 0;
    2191             :         c->interfaces      = NULL;
    2192             : 
    2193             : #else
    2194             : # error unknow Java configuration
    2195             : #endif
    2196             : 
    2197        4944 :         c->methodscount = 1;
    2198        4944 :         c->methods      = MNEW(methodinfo, c->methodscount);
    2199             : 
    2200        4944 :         MZERO(c->methods, methodinfo, c->methodscount);
    2201             : 
    2202        4944 :         classrefs = MNEW(constant_classref, 2);
    2203             : 
    2204        4944 :         new (classrefs + 0) constant_classref(c, c->name);
    2205        4944 :         new (classrefs + 1) constant_classref(c, utf8::java_lang_Object);
    2206             : 
    2207             :         /* create descriptor for clone method */
    2208             :         /* we need one paramslot which is reserved for the 'this' parameter */
    2209        4944 :         clonedesc = NEW(methoddesc);
    2210        4944 :         clonedesc->returntype.type     = TYPE_ADR;
    2211        4944 :         clonedesc->returntype.classref = classrefs + 1;
    2212        4944 :         clonedesc->returntype.arraydim = 0;
    2213             :         // initialize params to "empty", add real params below in
    2214             :         // params_from_paramtypes
    2215        4944 :         clonedesc->paramcount = 0;
    2216        4944 :         clonedesc->paramslots = 0;
    2217        4944 :         clonedesc->paramtypes[0].classref = classrefs + 0;
    2218        4944 :         clonedesc->params = NULL;
    2219        4944 :         clonedesc->pool_lock = NULL;
    2220             : 
    2221             :         /* create methodinfo */
    2222             : 
    2223        4944 :         clone = c->methods;
    2224        4944 :         MSET(clone, 0, methodinfo, 1);
    2225             : 
    2226             :         /* ATTENTION: if you delete the ACC_NATIVE below, set
    2227             :            clone->maxlocals=1 (interpreter related) */
    2228             : 
    2229        4944 :         clone->mutex      = new Mutex();
    2230        4944 :         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
    2231        4944 :         clone->name       = utf8::clone;
    2232        4944 :         clone->descriptor = utf8::void__java_lang_Object;
    2233        4944 :         clone->parseddesc = clonedesc;
    2234        4944 :         clone->clazz      = c;
    2235             : 
    2236             :         /* parse the descriptor to get the register allocation */
    2237             : 
    2238        4944 :         clonedesc->params_from_paramtypes(clone->flags);
    2239             : 
    2240        4944 :         clone->code = NativeStub::generate(clone, BUILTIN_clone);
    2241             : 
    2242             :         /* XXX: field: length? */
    2243             : 
    2244             :         /* array classes are not loaded from class files */
    2245             : 
    2246        4944 :         c->state          |= CLASS_LOADED;
    2247        4944 :         c->classrefs      = classrefs;
    2248        4944 :         c->classrefcount  = 1;
    2249             : 
    2250             :         /* insert class into the loaded class cache */
    2251             :         /* XXX free classinfo if NULL returned? */
    2252             : 
    2253        4944 :         return classcache_store(loader, c, true);
    2254             : }
    2255             : 
    2256             : 
    2257             : /* loader_close ****************************************************************
    2258             : 
    2259             :    Frees all resources.
    2260             : 
    2261             : *******************************************************************************/
    2262             : 
    2263           0 : void loader_close(void)
    2264             : {
    2265             :         /* empty */
    2266         495 : }
    2267             : 
    2268             : 
    2269             : /*
    2270             :  * These are local overrides for various environment variables in Emacs.
    2271             :  * Please do not remove this and leave it at the end of the file, where
    2272             :  * Emacs will automagically detect them.
    2273             :  * ---------------------------------------------------------------------
    2274             :  * Local variables:
    2275             :  * mode: c++
    2276             :  * indent-tabs-mode: t
    2277             :  * c-basic-offset: 4
    2278             :  * tab-width: 4
    2279             :  * End:
    2280             :  * vim:noexpandtab:sw=4:ts=4:
    2281             :  */

Generated by: LCOV version 1.11