1 /* src/vm/loader.cpp - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2009 Theobroma Systems Ltd.
7 This file is part of CACAO.
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.
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.
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
35 #include "mm/dumpmemory.hpp"
36 #include "mm/memory.hpp"
38 #include "native/llni.h"
40 #include "threads/mutex.hpp"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.hpp"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/classcache.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/field.hpp"
49 #include "vm/global.h"
50 #include "vm/globals.hpp"
51 #include "vm/javaobjects.hpp"
52 #include "vm/linker.hpp"
53 #include "vm/loader.hpp"
54 #include "vm/method.hpp"
55 #include "vm/options.h"
56 #include "vm/package.hpp"
57 #include "vm/primitive.hpp"
58 #include "vm/resolve.hpp"
59 #include "vm/rt-timing.h"
60 #include "vm/string.hpp"
61 #include "vm/suck.hpp"
65 #if defined(ENABLE_JAVASE)
66 # include "vm/annotation.hpp"
67 # include "vm/stackmap.h"
70 #if defined(ENABLE_STATISTICS)
71 # include "vm/statistics.h"
74 #if defined(ENABLE_ZLIB)
75 # include "vm/zip.hpp"
78 #include "vm/jit/stubs.hpp"
80 #if defined(ENABLE_JVMTI)
81 # include "native/jvmti/cacaodbg.h"
85 /* global variables ***********************************************************/
87 static hashtable *hashtable_classloader;
90 /* loader_preinit **************************************************************
92 Initializes the classpath list and loads classes required for the
95 NOTE: Exceptions thrown during VM initialization are caught in the
96 exception functions themselves.
98 *******************************************************************************/
100 void loader_preinit(void)
102 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
104 #if defined(ENABLE_THREADS)
105 // Get current list of classpath entries.
106 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
108 /* Initialize the monitor pointer for zip/jar file locking. */
110 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
111 list_classpath_entry* lce = *it;
113 if (lce->type == CLASSPATH_ARCHIVE)
114 lce->mutex = new Mutex();
118 /* initialize classloader hashtable, 10 entries should be enough */
120 hashtable_classloader = NEW(hashtable);
121 hashtable_create(hashtable_classloader, 10);
123 /* Load the most basic classes. */
125 assert(VM::get_current()->is_initializing() == true);
127 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
129 #if defined(ENABLE_JAVASE)
130 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
131 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
136 /* loader_init *****************************************************************
138 Loads all classes required in the VM.
140 NOTE: Exceptions thrown during VM initialization are caught in the
141 exception functions themselves.
143 *******************************************************************************/
145 void loader_init(void)
147 TRACESUBSYSTEMINITIALIZATION("loader_init");
149 /* Load primitive-type wrapping classes. */
151 assert(VM::get_current()->is_initializing() == true);
153 #if defined(ENABLE_JAVASE)
154 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
157 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
158 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
159 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
160 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
161 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
162 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
163 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
164 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
166 /* Load important system classes. */
168 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
169 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
171 #if defined(ENABLE_JAVASE)
172 class_java_lang_ClassLoader =
173 load_class_bootstrap(utf_java_lang_ClassLoader);
175 class_java_lang_SecurityManager =
176 load_class_bootstrap(utf_java_lang_SecurityManager);
179 class_java_lang_System =
180 load_class_bootstrap(utf_new_char("java/lang/System"));
182 class_java_lang_Thread =
183 load_class_bootstrap(utf_new_char("java/lang/Thread"));
185 #if defined(ENABLE_JAVASE)
186 class_java_lang_ThreadGroup =
187 load_class_bootstrap(utf_java_lang_ThreadGroup);
190 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
192 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
193 class_java_lang_VMSystem =
194 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
196 class_java_lang_VMThread =
197 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
199 class_java_lang_VMThrowable =
200 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
203 /* Important system exceptions. */
205 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
207 class_java_lang_ClassNotFoundException =
208 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
210 class_java_lang_RuntimeException =
211 load_class_bootstrap(utf_java_lang_RuntimeException);
213 /* Some classes which may be used often. */
215 #if defined(ENABLE_JAVASE)
216 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
218 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
219 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
220 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
222 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
223 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
224 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
225 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
228 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
230 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
231 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
233 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
234 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
235 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
238 arrayclass_java_lang_Object =
239 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
241 # if defined(ENABLE_ANNOTATIONS)
242 /* needed by annotation support */
243 class_sun_reflect_ConstantPool =
244 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
246 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
247 /* needed by GNU Classpaths annotation support */
248 class_sun_reflect_annotation_AnnotationParser =
249 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
256 /* loader_hashtable_classloader_add ********************************************
258 Adds an entry to the classloader hashtable.
260 REMEMBER: Also use this to register native loaders!
262 *******************************************************************************/
264 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
266 hashtable_classloader_entry *cle;
273 hashtable_classloader->mutex->lock();
277 /* key for entry is the hashcode of the classloader;
278 aligned to 16-byte boundaries */
280 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
281 slot = key & (hashtable_classloader->size - 1);
282 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
284 /* search hashchain for existing entry */
287 if (cle->object == LLNI_DIRECT(cl))
295 /* if no classloader was found, we create a new entry here */
298 cle = NEW(hashtable_classloader_entry);
300 #if defined(ENABLE_GC_CACAO)
301 /* register the classloader object with the GC */
303 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
308 cle->object = LLNI_DIRECT(cl);
312 /*#define LOADER_DEBUG_CLASSLOADER*/
313 #ifdef LOADER_DEBUG_CLASSLOADER
314 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
315 class_print(LLNI_vftbl_direct(cl)->class);
320 /* insert entry into hashtable */
322 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
323 hashtable_classloader->ptr[slot] = cle;
325 /* update number of entries */
327 hashtable_classloader->entries++;
330 hashtable_classloader->mutex->unlock();
332 #if defined(ENABLE_HANDLES)
340 /* loader_hashtable_classloader_find *******************************************
342 Find an entry in the classloader hashtable.
344 *******************************************************************************/
346 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
348 hashtable_classloader_entry *cle;
357 /* key for entry is the hashcode of the classloader;
358 aligned to 16-byte boundaries */
360 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
361 slot = key & (hashtable_classloader->size - 1);
362 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
364 /* search hashchain for existing entry */
367 if (cle->object == LLNI_DIRECT(cl))
373 #ifdef LOADER_DEBUG_CLASSLOADER
375 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
376 class_print(LLNI_vftbl_direct(cl)->class);
384 #if defined(ENABLE_HANDLES)
392 /* loader_load_all_classes *****************************************************
394 Loads all classes specified in the BOOTCLASSPATH.
396 *******************************************************************************/
398 void loader_load_all_classes(void)
400 #if defined(ENABLE_ZLIB)
402 hashtable_zipfile_entry *htzfe;
406 // Get current list of classpath entries.
407 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
409 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
410 list_classpath_entry* lce = *it;
412 #if defined(ENABLE_ZLIB)
413 if (lce->type == CLASSPATH_ARCHIVE) {
414 /* get the classes hashtable */
418 for (uint32_t slot = 0; slot < ht->size; slot++) {
419 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
421 for (; htzfe; htzfe = htzfe->hashlink) {
424 /* skip all entries in META-INF and .properties,
427 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
428 strstr(u->text, ".properties") ||
429 strstr(u->text, ".png"))
432 /* load class from bootstrap classloader */
434 if (!load_class_bootstrap(u)) {
435 fprintf(stderr, "Error loading: ");
436 utf_fprint_printable_ascii_classname(stderr, u);
437 fprintf(stderr, "\n");
440 /* print out exception and cause */
442 exceptions_print_current_exception();
450 #if defined(ENABLE_ZLIB)
457 /* loader_skip_attribute_body **************************************************
459 Skips an attribute the attribute_name_index has already been read.
462 u2 attribute_name_index;
464 u1 info[attribute_length];
467 *******************************************************************************/
469 bool loader_skip_attribute_body(classbuffer *cb)
473 if (!suck_check_classbuffer_size(cb, 4))
476 attribute_length = suck_u4(cb);
478 if (!suck_check_classbuffer_size(cb, attribute_length))
481 suck_skip_nbytes(cb, attribute_length);
487 /* load_constantpool ***********************************************************
489 Loads the constantpool of a class, the entries are transformed into
490 a simpler format by resolving references (a detailed overview of
491 the compact structures can be found in global.h).
493 *******************************************************************************/
495 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
498 /* The following structures are used to save information which cannot be
499 processed during the first pass. After the complete constantpool has
500 been traversed the references can be resolved.
501 (only in specific order) */
503 /* CONSTANT_Class entries */
504 typedef struct forward_class {
505 struct forward_class *next;
510 /* CONSTANT_String */
511 typedef struct forward_string {
512 struct forward_string *next;
517 /* CONSTANT_NameAndType */
518 typedef struct forward_nameandtype {
519 struct forward_nameandtype *next;
523 } forward_nameandtype;
525 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
526 typedef struct forward_fieldmethint {
527 struct forward_fieldmethint *next;
531 u2 nameandtype_index;
532 } forward_fieldmethint;
538 forward_class *forward_classes = NULL;
539 forward_string *forward_strings = NULL;
540 forward_nameandtype *forward_nameandtypes = NULL;
541 forward_fieldmethint *forward_fieldmethints = NULL;
545 forward_nameandtype *nfn;
546 forward_fieldmethint *nff;
554 /* number of entries in the constant_pool table plus one */
555 if (!suck_check_classbuffer_size(cb, 2))
558 cpcount = c->cpcount = suck_u2(cb);
560 /* allocate memory */
561 cptags = c->cptags = MNEW(u1, cpcount);
562 cpinfos = c->cpinfos = MNEW(void*, cpcount);
565 exceptions_throw_classformaterror(c, "Illegal constant pool size");
569 #if defined(ENABLE_STATISTICS)
571 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
574 /* initialize constantpool */
575 for (idx = 0; idx < cpcount; idx++) {
576 cptags[idx] = CONSTANT_UNUSED;
581 /******* first pass *******/
582 /* entries which cannot be resolved now are written into
583 temporary structures and traversed again later */
586 while (idx < cpcount) {
589 /* get constant type */
590 if (!suck_check_classbuffer_size(cb, 1))
598 nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
600 nfc->next = forward_classes;
601 forward_classes = nfc;
603 nfc->thisindex = idx;
604 /* reference to CONSTANT_NameAndType */
605 if (!suck_check_classbuffer_size(cb, 2))
608 nfc->name_index = suck_u2(cb);
613 case CONSTANT_String:
615 nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
617 nfs->next = forward_strings;
618 forward_strings = nfs;
620 nfs->thisindex = idx;
622 /* reference to CONSTANT_Utf8_info with string characters */
623 if (!suck_check_classbuffer_size(cb, 2))
626 nfs->string_index = suck_u2(cb);
631 case CONSTANT_NameAndType:
633 nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
635 nfn->next = forward_nameandtypes;
636 forward_nameandtypes = nfn;
638 nfn->thisindex = idx;
640 if (!suck_check_classbuffer_size(cb, 2 + 2))
643 /* reference to CONSTANT_Utf8_info containing simple name */
644 nfn->name_index = suck_u2(cb);
646 /* reference to CONSTANT_Utf8_info containing field or method
648 nfn->sig_index = suck_u2(cb);
653 case CONSTANT_Fieldref:
654 case CONSTANT_Methodref:
655 case CONSTANT_InterfaceMethodref:
657 nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
659 nff->next = forward_fieldmethints;
660 forward_fieldmethints = nff;
662 nff->thisindex = idx;
666 if (!suck_check_classbuffer_size(cb, 2 + 2))
669 /* class or interface type that contains the declaration of the
671 nff->class_index = suck_u2(cb);
673 /* name and descriptor of the field or method */
674 nff->nameandtype_index = suck_u2(cb);
679 case CONSTANT_Integer: {
680 constant_integer *ci = NEW(constant_integer);
682 #if defined(ENABLE_STATISTICS)
684 count_const_pool_len += sizeof(constant_integer);
687 if (!suck_check_classbuffer_size(cb, 4))
690 ci->value = suck_s4(cb);
691 cptags[idx] = CONSTANT_Integer;
698 case CONSTANT_Float: {
699 constant_float *cf = NEW(constant_float);
701 #if defined(ENABLE_STATISTICS)
703 count_const_pool_len += sizeof(constant_float);
706 if (!suck_check_classbuffer_size(cb, 4))
709 cf->value = suck_float(cb);
710 cptags[idx] = CONSTANT_Float;
717 case CONSTANT_Long: {
718 constant_long *cl = NEW(constant_long);
720 #if defined(ENABLE_STATISTICS)
722 count_const_pool_len += sizeof(constant_long);
725 if (!suck_check_classbuffer_size(cb, 8))
728 cl->value = suck_s8(cb);
729 cptags[idx] = CONSTANT_Long;
733 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
739 case CONSTANT_Double: {
740 constant_double *cd = NEW(constant_double);
742 #if defined(ENABLE_STATISTICS)
744 count_const_pool_len += sizeof(constant_double);
747 if (!suck_check_classbuffer_size(cb, 8))
750 cd->value = suck_double(cb);
751 cptags[idx] = CONSTANT_Double;
755 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
761 case CONSTANT_Utf8: {
764 /* number of bytes in the bytes array (not string-length) */
765 if (!suck_check_classbuffer_size(cb, 2))
768 length = suck_u2(cb);
769 cptags[idx] = CONSTANT_Utf8;
771 /* validate the string */
772 if (!suck_check_classbuffer_size(cb, length))
775 #ifdef ENABLE_VERIFIER
777 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
779 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
782 #endif /* ENABLE_VERIFIER */
783 /* insert utf-string into the utf-symboltable */
784 cpinfos[idx] = utf_new((char *) cb->pos, length);
786 /* skip bytes of the string (buffer size check above) */
787 suck_skip_nbytes(cb, length);
793 exceptions_throw_classformaterror(c, "Illegal constant pool type");
799 /* resolve entries in temporary structures */
801 while (forward_classes) {
802 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
806 #ifdef ENABLE_VERIFIER
807 if (opt_verify && !is_valid_name_utf(name)) {
808 exceptions_throw_classformaterror(c, "Class reference with invalid name");
811 #endif /* ENABLE_VERIFIER */
813 /* add all class references to the descriptor_pool */
815 if (!descriptor_pool_add_class(descpool, name))
818 cptags[forward_classes->thisindex] = CONSTANT_Class;
820 /* the classref is created later */
821 cpinfos[forward_classes->thisindex] = name;
823 nfc = forward_classes;
824 forward_classes = forward_classes->next;
827 while (forward_strings) {
828 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
833 /* resolve utf-string */
834 cptags[forward_strings->thisindex] = CONSTANT_String;
835 cpinfos[forward_strings->thisindex] = text;
837 nfs = forward_strings;
838 forward_strings = forward_strings->next;
841 while (forward_nameandtypes) {
842 constant_nameandtype *cn = NEW(constant_nameandtype);
844 #if defined(ENABLE_STATISTICS)
846 count_const_pool_len += sizeof(constant_nameandtype);
849 /* resolve simple name and descriptor */
850 cn->name = (utf*) class_getconstant(c,
851 forward_nameandtypes->name_index,
856 cn->descriptor = (utf*) class_getconstant(c,
857 forward_nameandtypes->sig_index,
862 #ifdef ENABLE_VERIFIER
865 if (!is_valid_name_utf(cn->name)) {
866 exceptions_throw_classformaterror(c,
867 "Illegal Field name \"%s\"",
873 /* disallow referencing <clinit> among others */
874 if (cn->name->text[0] == '<' && cn->name != utf_init) {
875 exceptions_throw_classformaterror(c, "Illegal reference to special method");
879 #endif /* ENABLE_VERIFIER */
881 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
882 cpinfos[forward_nameandtypes->thisindex] = cn;
884 nfn = forward_nameandtypes;
885 forward_nameandtypes = forward_nameandtypes->next;
888 while (forward_fieldmethints) {
889 constant_nameandtype *nat;
890 constant_FMIref *fmi = NEW(constant_FMIref);
892 #if defined(ENABLE_STATISTICS)
894 count_const_pool_len += sizeof(constant_FMIref);
896 /* resolve simple name and descriptor */
898 nat = (constant_nameandtype*) class_getconstant(c,
899 forward_fieldmethints->nameandtype_index,
900 CONSTANT_NameAndType);
905 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
907 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
910 /* the classref is created later */
912 fmi->p.index = forward_fieldmethints->class_index;
913 fmi->name = nat->name;
914 fmi->descriptor = nat->descriptor;
916 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
917 cpinfos[forward_fieldmethints->thisindex] = fmi;
919 nff = forward_fieldmethints;
920 forward_fieldmethints = forward_fieldmethints->next;
923 /* everything was ok */
929 /* loader_load_attribute_signature *********************************************
931 Signature_attribute {
932 u2 attribute_name_index;
937 *******************************************************************************/
939 #if defined(ENABLE_JAVASE)
940 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
950 /* check remaining bytecode */
952 if (!suck_check_classbuffer_size(cb, 4 + 2))
955 /* check attribute length */
957 attribute_length = suck_u4(cb);
959 if (attribute_length != 2) {
960 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
964 if (*signature != NULL) {
965 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
971 signature_index = suck_u2(cb);
973 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
975 if (*signature == NULL)
980 #endif /* defined(ENABLE_JAVASE) */
983 /* load_class_from_sysloader ***************************************************
985 Load the class with the given name using the system class loader
988 name.............the classname
992 NULL if an exception has been thrown
994 *******************************************************************************/
996 #if defined(ENABLE_JAVASE)
997 classinfo *load_class_from_sysloader(utf *name)
1002 cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
1007 c = load_class_from_classloader(name, cl);
1011 #endif /* defined(ENABLE_JAVASE) */
1014 /* load_class_from_classloader *************************************************
1016 Load the class with the given name using the given user-defined class loader.
1019 name.............the classname
1020 cl...............user-defined class loader
1023 the loaded class, or
1024 NULL if an exception has been thrown
1026 *******************************************************************************/
1028 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1033 java_handle_t *string;
1034 #if defined(ENABLE_RT_TIMING)
1035 struct timespec time_start, time_lookup, time_prepare, time_java,
1039 RT_TIMING_GET_TIME(time_start);
1043 /* lookup if this class has already been loaded */
1045 c = classcache_lookup(cl, name);
1047 RT_TIMING_GET_TIME(time_lookup);
1048 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1053 /* if other class loader than bootstrap, call it */
1061 namelen = name->blength;
1063 /* handle array classes */
1064 if (text[0] == '[') {
1070 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1071 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1072 exceptions_throw_classnotfoundexception(name);
1076 u = utf_new(text + 2, namelen - 3);
1078 if (!(comp = load_class_from_classloader(u, cl)))
1081 /* create the array class */
1083 c = class_array_of(comp, false);
1085 tmpc = classcache_store(cl, c, true);
1088 /* exception, free the loaded class */
1089 c->state &= ~CLASS_LOADING;
1096 /* load the component class */
1098 u = utf_new(text + 1, namelen - 1);
1100 if (!(comp = load_class_from_classloader(u, cl)))
1103 /* create the array class */
1105 c = class_array_of(comp, false);
1107 tmpc = classcache_store(cl, c, true);
1110 /* exception, free the loaded class */
1111 c->state &= ~CLASS_LOADING;
1118 /* primitive array classes are loaded by the bootstrap loader */
1120 c = load_class_bootstrap(name);
1126 LLNI_class_get(cl, c);
1128 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1129 /* OpenJDK uses this internal function because it's
1132 lc = class_resolveclassmethod(c,
1133 utf_loadClassInternal,
1134 utf_java_lang_String__java_lang_Class,
1138 lc = class_resolveclassmethod(c,
1140 utf_java_lang_String__java_lang_Class,
1146 return false; /* exception */
1148 /* move return value into `o' and cast it afterwards to a classinfo* */
1150 string = javastring_new_slash_to_dot(name);
1152 RT_TIMING_GET_TIME(time_prepare);
1154 o = vm_call_method(lc, (java_handle_t *) cl, string);
1156 RT_TIMING_GET_TIME(time_java);
1158 c = LLNI_classinfo_unwrap(o);
1161 /* Store this class in the loaded class cache. If another
1162 class with the same (initloader,name) pair has been
1163 stored earlier it will be returned by classcache_store
1164 In this case classcache_store may not free the class
1165 because it has already been exposed to Java code which
1166 may have kept references to that class. */
1168 tmpc = classcache_store(cl, c, false);
1171 /* exception, free the loaded class */
1172 c->state &= ~CLASS_LOADING;
1179 // Expected behavior for the classloader is to throw an exception
1180 // and never return NULL. If the classloader shows a different
1181 // behavior, we are correcting it here (see PR126).
1182 if (exceptions_get_exception() == NULL) {
1183 #if !defined(NDEBUG)
1184 if (opt_PrintWarnings)
1185 log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1187 exceptions_throw_classnotfoundexception(name);
1191 RT_TIMING_GET_TIME(time_cache);
1193 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1194 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1195 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1197 /* SUN compatible -verbose:class output */
1199 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1201 utf_display_printable_ascii_classname(name);
1205 #if defined(ENABLE_JVMTI)
1206 /* fire Class Load JVMTI event */
1207 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1214 c = load_class_bootstrap(name);
1220 /* load_class_bootstrap ********************************************************
1222 Load the class with the given name using the bootstrap class loader.
1225 name.............the classname
1228 loaded classinfo, or
1229 NULL if an exception has been thrown
1232 load_class_bootstrap is synchronized. It can be treated as an
1235 *******************************************************************************/
1237 classinfo *load_class_bootstrap(utf *name)
1242 #if defined(ENABLE_RT_TIMING)
1243 struct timespec time_start, time_lookup, time_array, time_suck,
1244 time_load, time_cache;
1247 RT_TIMING_GET_TIME(time_start);
1253 /* lookup if this class has already been loaded */
1255 r = classcache_lookup(NULL, name);
1258 RT_TIMING_GET_TIME(time_lookup);
1259 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1264 RT_TIMING_GET_TIME(time_lookup);
1265 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1267 /* create the classinfo */
1269 c = class_create_classinfo(name);
1271 /* handle array classes */
1273 if (name->text[0] == '[') {
1274 c = load_newly_created_array(c, NULL);
1279 assert(c->state & CLASS_LOADED);
1281 RT_TIMING_GET_TIME(time_array);
1282 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1287 #if defined(ENABLE_STATISTICS)
1290 if (opt_getcompilingtime)
1291 compilingtime_stop();
1293 if (opt_getloadingtime)
1294 loadingtime_start();
1297 /* load classdata, throw exception on error */
1302 exceptions_throw_classnotfoundexception(name);
1306 RT_TIMING_GET_TIME(time_suck);
1308 /* load the class from the buffer */
1310 r = load_class_from_classbuffer(cb);
1312 RT_TIMING_GET_TIME(time_load);
1315 /* the class could not be loaded, free the classinfo struct */
1320 /* Store this class in the loaded class cache this step also
1321 checks the loading constraints. If the class has been
1322 loaded before, the earlier loaded class is returned. */
1324 classinfo *res = classcache_store(NULL, c, true);
1331 // Add the package name to the boot packages.
1332 Package::add(c->packagename);
1338 RT_TIMING_GET_TIME(time_cache);
1340 /* SUN compatible -verbose:class output */
1342 if (opt_verboseclass && r) {
1344 utf_display_printable_ascii_classname(name);
1345 printf(" from %s]\n", cb->path);
1352 #if defined(ENABLE_STATISTICS)
1355 if (opt_getloadingtime)
1358 if (opt_getcompilingtime)
1359 compilingtime_start();
1362 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1363 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1364 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1365 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1371 /* load_class_from_classbuffer_intern ******************************************
1373 Loads a class from a classbuffer into a given classinfo structure.
1374 Super-classes are also loaded at this point and some verfication
1378 This function is NOT synchronized!
1380 *******************************************************************************/
1382 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1388 utf **interfacesnames;
1390 constant_classref *cr;
1394 descriptor_pool *descpool;
1395 #if defined(ENABLE_STATISTICS)
1399 #if defined(ENABLE_RT_TIMING)
1400 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1401 time_setup, time_fields, time_methods, time_classrefs,
1402 time_descs, time_setrefs, time_parsefds, time_parsemds,
1403 time_parsecpool, time_verify, time_attrs;
1406 // Create new dump memory area.
1409 RT_TIMING_GET_TIME(time_start);
1411 /* Get the classbuffer's class. */
1415 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1418 /* check signature */
1420 if (suck_u4(cb) != MAGIC) {
1421 exceptions_throw_classformaterror(c, "Bad magic number");
1430 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1431 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1435 RT_TIMING_GET_TIME(time_checks);
1437 /* create a new descriptor pool */
1439 descpool = descriptor_pool_new(c);
1441 RT_TIMING_GET_TIME(time_ndpool);
1443 /* load the constant pool */
1445 if (!load_constantpool(cb, descpool))
1448 RT_TIMING_GET_TIME(time_cpool);
1452 if (!suck_check_classbuffer_size(cb, 2))
1455 /* We OR the flags here, as we set already some flags in
1456 class_create_classinfo. */
1458 c->flags |= suck_u2(cb);
1460 /* check ACC flags consistency */
1462 if (c->flags & ACC_INTERFACE) {
1463 if (!(c->flags & ACC_ABSTRACT)) {
1464 /* We work around this because interfaces in JDK 1.1 are
1465 * not declared abstract. */
1467 c->flags |= ACC_ABSTRACT;
1470 if (c->flags & ACC_FINAL) {
1471 exceptions_throw_classformaterror(c,
1472 "Illegal class modifiers: 0x%X",
1477 if (c->flags & ACC_SUPER) {
1478 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1482 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1483 exceptions_throw_classformaterror(c,
1484 "Illegal class modifiers: 0x%X",
1489 if (!suck_check_classbuffer_size(cb, 2 + 2))
1494 index = suck_u2(cb);
1496 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1501 if (c->name == utf_not_named_yet) {
1502 /* we finally have a name for this class */
1504 class_set_packagename(c);
1506 else if (name != c->name) {
1507 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1511 /* Retrieve superclass. */
1515 index = suck_u2(cb);
1520 /* This is only allowed for java.lang.Object. */
1522 if (c->name != utf_java_lang_Object) {
1523 exceptions_throw_classformaterror(c, "Bad superclass index");
1528 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1530 if (supername == NULL)
1533 /* java.lang.Object may not have a super class. */
1535 if (c->name == utf_java_lang_Object) {
1536 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1540 /* Detect circularity. */
1542 if (supername == c->name) {
1543 exceptions_throw_classcircularityerror(c);
1547 /* Interfaces must have java.lang.Object as super class. */
1549 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1550 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1555 /* Parse the super interfaces. */
1557 if (!suck_check_classbuffer_size(cb, 2))
1560 c->interfacescount = suck_u2(cb);
1562 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1565 c->interfaces = MNEW(classinfo*, c->interfacescount);
1567 /* Get the names of the super interfaces. */
1569 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1571 for (int32_t i = 0; i < c->interfacescount; i++) {
1572 index = suck_u2(cb);
1574 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1579 interfacesnames[i] = u;
1582 RT_TIMING_GET_TIME(time_setup);
1586 if (!suck_check_classbuffer_size(cb, 2))
1589 c->fieldscount = suck_u2(cb);
1590 c->fields = MNEW(fieldinfo, c->fieldscount);
1592 MZERO(c->fields, fieldinfo, c->fieldscount);
1594 for (int32_t i = 0; i < c->fieldscount; i++) {
1595 if (!field_load(cb, &(c->fields[i]), descpool))
1599 RT_TIMING_GET_TIME(time_fields);
1601 /* Parse methods. */
1603 if (!suck_check_classbuffer_size(cb, 2))
1606 c->methodscount = suck_u2(cb);
1607 c->methods = MNEW(methodinfo, c->methodscount);
1609 MZERO(c->methods, methodinfo, c->methodscount);
1611 for (int32_t i = 0; i < c->methodscount; i++) {
1612 if (!method_load(cb, &(c->methods[i]), descpool))
1616 RT_TIMING_GET_TIME(time_methods);
1618 /* create the class reference table */
1621 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1623 RT_TIMING_GET_TIME(time_classrefs);
1625 /* allocate space for the parsed descriptors */
1627 descriptor_pool_alloc_parsed_descriptors(descpool);
1628 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1630 #if defined(ENABLE_STATISTICS)
1632 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1633 count_classref_len += classrefsize;
1634 count_parsed_desc_len += descsize;
1638 RT_TIMING_GET_TIME(time_descs);
1640 /* put the classrefs in the constant pool */
1642 for (int32_t i = 0; i < c->cpcount; i++) {
1643 if (c->cptags[i] == CONSTANT_Class) {
1644 utf *name = (utf *) c->cpinfos[i];
1645 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1649 /* Resolve the super class. */
1651 if (supername != NULL) {
1652 cr = descriptor_pool_lookup_classref(descpool, supername);
1657 /* XXX This should be done better. */
1658 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1661 resolve_handle_pending_exception(true);
1665 /* Interfaces are not allowed as super classes. */
1667 if (tc->flags & ACC_INTERFACE) {
1668 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1672 /* Don't allow extending final classes */
1674 if (tc->flags & ACC_FINAL) {
1675 exceptions_throw_verifyerror(NULL,
1676 "Cannot inherit from final class");
1680 /* Store the super class. */
1685 /* Resolve the super interfaces. */
1687 for (int32_t i = 0; i < c->interfacescount; i++) {
1688 u = interfacesnames[i];
1689 cr = descriptor_pool_lookup_classref(descpool, u);
1694 /* XXX This should be done better. */
1695 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1698 resolve_handle_pending_exception(true);
1702 /* Detect circularity. */
1705 exceptions_throw_classcircularityerror(c);
1709 if (!(tc->flags & ACC_INTERFACE)) {
1710 exceptions_throw_incompatibleclasschangeerror(tc,
1711 "Implementing class");
1715 /* Store the super interface. */
1717 c->interfaces[i] = tc;
1720 RT_TIMING_GET_TIME(time_setrefs);
1722 /* Parse the field descriptors. */
1724 for (int32_t i = 0; i < c->fieldscount; i++) {
1725 c->fields[i].parseddesc =
1726 descriptor_pool_parse_field_descriptor(descpool,
1727 c->fields[i].descriptor);
1728 if (!c->fields[i].parseddesc)
1732 RT_TIMING_GET_TIME(time_parsefds);
1734 /* parse method descriptors */
1736 for (int32_t i = 0; i < c->methodscount; i++) {
1737 methodinfo *m = &c->methods[i];
1739 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1740 m->flags, class_get_self_classref(m->clazz));
1744 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1745 if (!m->rawexceptiontable[j].catchtype.any)
1748 if ((m->rawexceptiontable[j].catchtype.ref =
1749 descriptor_pool_lookup_classref(descpool,
1750 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1754 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1755 if (!m->thrownexceptions[j].any)
1758 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1759 (utf *) m->thrownexceptions[j].any)) == NULL)
1764 RT_TIMING_GET_TIME(time_parsemds);
1766 /* parse the loaded descriptors */
1768 for (int32_t i = 0; i < c->cpcount; i++) {
1769 constant_FMIref *fmi;
1772 switch (c->cptags[i]) {
1773 case CONSTANT_Fieldref:
1774 fmi = (constant_FMIref *) c->cpinfos[i];
1775 fmi->parseddesc.fd =
1776 descriptor_pool_parse_field_descriptor(descpool,
1778 if (!fmi->parseddesc.fd)
1781 index = fmi->p.index;
1783 (constant_classref *) class_getconstant(c, index,
1785 if (!fmi->p.classref)
1788 case CONSTANT_Methodref:
1789 case CONSTANT_InterfaceMethodref:
1790 fmi = (constant_FMIref *) c->cpinfos[i];
1791 index = fmi->p.index;
1793 (constant_classref *) class_getconstant(c, index,
1795 if (!fmi->p.classref)
1797 fmi->parseddesc.md =
1798 descriptor_pool_parse_method_descriptor(descpool,
1802 if (!fmi->parseddesc.md)
1808 RT_TIMING_GET_TIME(time_parsecpool);
1810 #ifdef ENABLE_VERIFIER
1811 /* Check if all fields and methods can be uniquely
1812 * identified by (name,descriptor). */
1815 /* We use a hash table here to avoid making the
1816 * average case quadratic in # of methods, fields.
1818 static int shift = 0;
1820 u2 *next; /* for chaining colliding hash entries */
1826 /* Allocate hashtable */
1827 len = c->methodscount;
1828 if (len < c->fieldscount) len = c->fieldscount;
1830 hashtab = MNEW(u2,(hashlen + len));
1831 next = hashtab + hashlen;
1833 /* Determine bitshift (to get good hash values) */
1843 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1845 for (int32_t i = 0; i < c->fieldscount; ++i) {
1846 fieldinfo *fi = c->fields + i;
1848 /* It's ok if we lose bits here */
1849 index = ((((size_t) fi->name) +
1850 ((size_t) fi->descriptor)) >> shift) % hashlen;
1852 if ((old = hashtab[index])) {
1856 if (c->fields[old].name == fi->name &&
1857 c->fields[old].descriptor == fi->descriptor) {
1858 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1861 } while ((old = next[old]));
1863 hashtab[index] = i + 1;
1867 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1869 for (int32_t i = 0; i < c->methodscount; ++i) {
1870 methodinfo *mi = c->methods + i;
1872 /* It's ok if we lose bits here */
1873 index = ((((size_t) mi->name) +
1874 ((size_t) mi->descriptor)) >> shift) % hashlen;
1876 if ((old = hashtab[index])) {
1880 if (c->methods[old].name == mi->name &&
1881 c->methods[old].descriptor == mi->descriptor) {
1882 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1885 } while ((old = next[old]));
1887 hashtab[index] = i + 1;
1890 MFREE(hashtab, u2, (hashlen + len));
1892 #endif /* ENABLE_VERIFIER */
1894 RT_TIMING_GET_TIME(time_verify);
1896 #if defined(ENABLE_STATISTICS)
1898 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1899 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1900 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1904 /* load attribute structures */
1906 if (!class_load_attributes(cb))
1909 /* Pre Java 1.5 version don't check this. This implementation is
1910 like Java 1.5 do it: for class file version 45.3 we don't check
1911 it, older versions are checked. */
1913 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1914 /* check if all data has been read */
1915 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1917 if (classdata_left > 0) {
1918 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1923 RT_TIMING_GET_TIME(time_attrs);
1925 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1926 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1927 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1928 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1929 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1930 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1931 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1932 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1933 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1934 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1935 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1936 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1937 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1938 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1939 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1945 /* load_class_from_classbuffer *************************************************
1947 Convenience wrapper for load_class_from_classbuffer.
1950 This function is NOT synchronized!
1952 *******************************************************************************/
1954 classinfo *load_class_from_classbuffer(classbuffer *cb)
1959 /* Get the classbuffer's class. */
1963 /* Check if the class is already loaded. */
1965 if (c->state & CLASS_LOADED)
1968 #if defined(ENABLE_STATISTICS)
1970 count_class_loads++;
1973 #if !defined(NDEBUG)
1975 log_message_class("Loading class: ", c);
1978 /* Class is currently loading. */
1980 c->state |= CLASS_LOADING;
1982 /* Parse the classbuffer. */
1984 result = load_class_from_classbuffer_intern(cb);
1986 /* An error occurred. */
1988 if (result == false) {
1989 /* Revert loading state. */
1991 c->state = (c->state & ~CLASS_LOADING);
1996 /* Revert loading state and set loaded. */
1998 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2000 #if defined(ENABLE_JVMTI)
2001 /* fire Class Prepare JVMTI event */
2004 jvmti_ClassLoadPrepare(true, c);
2007 #if !defined(NDEBUG)
2009 log_message_class("Loading done class: ", c);
2016 /* load_newly_created_array ****************************************************
2018 Load a newly created array class.
2021 c....................the array class C has been loaded
2022 other classinfo......the array class was found in the class cache,
2024 NULL.................an exception has been thrown
2027 This is an internal function. Do not use it unless you know exactly
2030 Use one of the load_class_... functions for general array class loading.
2032 *******************************************************************************/
2034 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2036 classinfo *comp = NULL;
2038 methoddesc *clonedesc;
2039 constant_classref *classrefs;
2044 text = c->name->text;
2045 namelen = c->name->blength;
2047 /* Check array class name */
2049 if ((namelen < 2) || (text[0] != '[')) {
2050 exceptions_throw_classnotfoundexception(c->name);
2054 /* Check the element type */
2058 /* c is an array of arrays. We have to create the component class. */
2060 u = utf_new(text + 1, namelen - 1);
2062 comp = load_class_from_classloader(u, loader);
2067 assert(comp->state & CLASS_LOADED);
2069 /* the array's flags are that of the component class */
2070 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2071 c->classloader = comp->classloader;
2075 /* c is an array of objects. */
2077 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2078 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2079 exceptions_throw_classnotfoundexception(c->name);
2083 u = utf_new(text + 2, namelen - 3);
2085 if (!(comp = load_class_from_classloader(u, loader)))
2088 assert(comp->state & CLASS_LOADED);
2090 /* the array's flags are that of the component class */
2091 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2092 c->classloader = comp->classloader;
2096 /* c is an array of a primitive type */
2098 /* check for cases like `[II' and whether the character is a
2099 valid primitive type */
2101 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2102 exceptions_throw_classnotfoundexception(c->name);
2106 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2107 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2108 c->classloader = NULL;
2111 assert(class_java_lang_Object);
2112 #if defined(ENABLE_JAVASE)
2113 assert(class_java_lang_Cloneable);
2114 assert(class_java_io_Serializable);
2117 /* Setup the array class. */
2119 c->super = class_java_lang_Object;
2121 #if defined(ENABLE_JAVASE)
2123 c->interfacescount = 2;
2124 c->interfaces = MNEW(classinfo*, 2);
2125 c->interfaces[0] = class_java_lang_Cloneable;
2126 c->interfaces[1] = class_java_io_Serializable;
2128 #elif defined(ENABLE_JAVAME_CLDC1_1)
2130 c->interfacescount = 0;
2131 c->interfaces = NULL;
2134 # error unknow Java configuration
2137 c->methodscount = 1;
2138 c->methods = MNEW(methodinfo, c->methodscount);
2140 MZERO(c->methods, methodinfo, c->methodscount);
2142 classrefs = MNEW(constant_classref, 2);
2144 CLASSREF_INIT(classrefs[0], c, c->name);
2145 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2147 /* create descriptor for clone method */
2148 /* we need one paramslot which is reserved for the 'this' parameter */
2149 clonedesc = NEW(methoddesc);
2150 clonedesc->returntype.type = TYPE_ADR;
2151 clonedesc->returntype.classref = classrefs + 1;
2152 clonedesc->returntype.arraydim = 0;
2153 /* initialize params to "empty", add real params below in
2154 descriptor_params_from_paramtypes */
2155 clonedesc->paramcount = 0;
2156 clonedesc->paramslots = 0;
2157 clonedesc->paramtypes[0].classref = classrefs + 0;
2158 clonedesc->params = NULL;
2160 /* create methodinfo */
2163 MSET(clone, 0, methodinfo, 1);
2165 /* ATTENTION: if you delete the ACC_NATIVE below, set
2166 clone->maxlocals=1 (interpreter related) */
2168 clone->mutex = new Mutex();
2169 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2170 clone->name = utf_clone;
2171 clone->descriptor = utf_void__java_lang_Object;
2172 clone->parseddesc = clonedesc;
2175 /* parse the descriptor to get the register allocation */
2177 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2180 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2182 /* XXX: field: length? */
2184 /* array classes are not loaded from class files */
2186 c->state |= CLASS_LOADED;
2187 c->parseddescs = (u1 *) clonedesc;
2188 c->parseddescsize = sizeof(methodinfo);
2189 c->classrefs = classrefs;
2190 c->classrefcount = 1;
2192 /* insert class into the loaded class cache */
2193 /* XXX free classinfo if NULL returned? */
2195 return classcache_store(loader, c, true);
2199 /* loader_close ****************************************************************
2201 Frees all resources.
2203 *******************************************************************************/
2205 void loader_close(void)
2212 * These are local overrides for various environment variables in Emacs.
2213 * Please do not remove this and leave it at the end of the file, where
2214 * Emacs will automagically detect them.
2215 * ---------------------------------------------------------------------
2218 * indent-tabs-mode: t
2222 * vim:noexpandtab:sw=4:ts=4: