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
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/dumpmemory.hpp"
35 #include "mm/memory.hpp"
37 #include "native/llni.h"
39 #include "threads/mutex.hpp"
41 #include "toolbox/hashtable.h"
42 #include "toolbox/logging.hpp"
44 #include "vm/jit/builtin.hpp"
45 #include "vm/classcache.hpp"
46 #include "vm/exceptions.hpp"
47 #include "vm/field.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/linker.hpp"
51 #include "vm/loader.hpp"
52 #include "vm/method.hpp"
53 #include "vm/options.h"
54 #include "vm/package.hpp"
55 #include "vm/primitive.hpp"
56 #include "vm/resolve.hpp"
57 #include "vm/rt-timing.h"
58 #include "vm/string.hpp"
59 #include "vm/suck.hpp"
63 #if defined(ENABLE_JAVASE)
64 # include "vm/annotation.hpp"
65 # include "vm/stackmap.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vm/statistics.h"
72 #if defined(ENABLE_ZLIB)
73 # include "vm/zip.hpp"
76 #include "vm/jit/stubs.hpp"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 static hashtable *hashtable_classloader;
88 /* loader_preinit **************************************************************
90 Initializes the classpath list and loads classes required for the
93 NOTE: Exceptions thrown during VM initialization are caught in the
94 exception functions themselves.
96 *******************************************************************************/
98 void loader_preinit(void)
100 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
102 #if defined(ENABLE_THREADS)
103 // Get current list of classpath entries.
104 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
106 /* Initialize the monitor pointer for zip/jar file locking. */
108 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
109 list_classpath_entry* lce = *it;
111 if (lce->type == CLASSPATH_ARCHIVE)
112 lce->mutex = new Mutex();
116 /* initialize classloader hashtable, 10 entries should be enough */
118 hashtable_classloader = NEW(hashtable);
119 hashtable_create(hashtable_classloader, 10);
121 /* Load the most basic classes. */
123 assert(VM::get_current()->is_initializing() == true);
125 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
127 #if defined(ENABLE_JAVASE)
128 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
129 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
134 /* loader_init *****************************************************************
136 Loads all classes required in the VM.
138 NOTE: Exceptions thrown during VM initialization are caught in the
139 exception functions themselves.
141 *******************************************************************************/
143 void loader_init(void)
145 TRACESUBSYSTEMINITIALIZATION("loader_init");
147 /* Load primitive-type wrapping classes. */
149 assert(VM::get_current()->is_initializing() == true);
151 #if defined(ENABLE_JAVASE)
152 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
155 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
156 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
157 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
158 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
159 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
160 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
161 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
162 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
164 /* Load important system classes. */
166 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
167 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
169 #if defined(ENABLE_JAVASE)
170 class_java_lang_ClassLoader =
171 load_class_bootstrap(utf_java_lang_ClassLoader);
173 class_java_lang_SecurityManager =
174 load_class_bootstrap(utf_java_lang_SecurityManager);
177 class_java_lang_System =
178 load_class_bootstrap(utf_new_char("java/lang/System"));
180 class_java_lang_Thread =
181 load_class_bootstrap(utf_new_char("java/lang/Thread"));
183 #if defined(ENABLE_JAVASE)
184 class_java_lang_ThreadGroup =
185 load_class_bootstrap(utf_java_lang_ThreadGroup);
188 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
190 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
191 class_java_lang_VMSystem =
192 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
194 class_java_lang_VMThread =
195 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
197 class_java_lang_VMThrowable =
198 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
201 /* Important system exceptions. */
203 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
205 class_java_lang_ClassNotFoundException =
206 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
208 class_java_lang_RuntimeException =
209 load_class_bootstrap(utf_java_lang_RuntimeException);
211 /* Some classes which may be used often. */
213 #if defined(ENABLE_JAVASE)
214 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
216 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
217 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
218 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
220 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
221 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
222 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
223 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
226 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
228 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
229 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
231 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
232 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
233 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
236 arrayclass_java_lang_Object =
237 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
239 # if defined(ENABLE_ANNOTATIONS)
240 /* needed by annotation support */
241 class_sun_reflect_ConstantPool =
242 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
244 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
245 /* needed by GNU Classpaths annotation support */
246 class_sun_reflect_annotation_AnnotationParser =
247 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
254 /* loader_hashtable_classloader_add ********************************************
256 Adds an entry to the classloader hashtable.
258 REMEMBER: Also use this to register native loaders!
260 *******************************************************************************/
262 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
264 hashtable_classloader_entry *cle;
271 hashtable_classloader->mutex->lock();
275 /* key for entry is the hashcode of the classloader;
276 aligned to 16-byte boundaries */
278 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
279 slot = key & (hashtable_classloader->size - 1);
280 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
282 /* search hashchain for existing entry */
285 if (cle->object == LLNI_DIRECT(cl))
293 /* if no classloader was found, we create a new entry here */
296 cle = NEW(hashtable_classloader_entry);
298 #if defined(ENABLE_GC_CACAO)
299 /* register the classloader object with the GC */
301 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
306 cle->object = LLNI_DIRECT(cl);
310 /*#define LOADER_DEBUG_CLASSLOADER*/
311 #ifdef LOADER_DEBUG_CLASSLOADER
312 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
313 class_print(LLNI_vftbl_direct(cl)->class);
318 /* insert entry into hashtable */
320 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
321 hashtable_classloader->ptr[slot] = cle;
323 /* update number of entries */
325 hashtable_classloader->entries++;
328 hashtable_classloader->mutex->unlock();
330 #if defined(ENABLE_HANDLES)
338 /* loader_hashtable_classloader_find *******************************************
340 Find an entry in the classloader hashtable.
342 *******************************************************************************/
344 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
346 hashtable_classloader_entry *cle;
355 /* key for entry is the hashcode of the classloader;
356 aligned to 16-byte boundaries */
358 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
359 slot = key & (hashtable_classloader->size - 1);
360 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
362 /* search hashchain for existing entry */
365 if (cle->object == LLNI_DIRECT(cl))
371 #ifdef LOADER_DEBUG_CLASSLOADER
373 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
374 class_print(LLNI_vftbl_direct(cl)->class);
382 #if defined(ENABLE_HANDLES)
390 /* loader_load_all_classes *****************************************************
392 Loads all classes specified in the BOOTCLASSPATH.
394 *******************************************************************************/
396 void loader_load_all_classes(void)
398 #if defined(ENABLE_ZLIB)
400 hashtable_zipfile_entry *htzfe;
404 // Get current list of classpath entries.
405 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
407 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
408 list_classpath_entry* lce = *it;
410 #if defined(ENABLE_ZLIB)
411 if (lce->type == CLASSPATH_ARCHIVE) {
412 /* get the classes hashtable */
416 for (uint32_t slot = 0; slot < ht->size; slot++) {
417 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
419 for (; htzfe; htzfe = htzfe->hashlink) {
422 /* skip all entries in META-INF and .properties,
425 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
426 strstr(u->text, ".properties") ||
427 strstr(u->text, ".png"))
430 /* load class from bootstrap classloader */
432 if (!load_class_bootstrap(u)) {
433 fprintf(stderr, "Error loading: ");
434 utf_fprint_printable_ascii_classname(stderr, u);
435 fprintf(stderr, "\n");
438 /* print out exception and cause */
440 exceptions_print_current_exception();
448 #if defined(ENABLE_ZLIB)
455 /* loader_skip_attribute_body **************************************************
457 Skips an attribute the attribute_name_index has already been read.
460 u2 attribute_name_index;
462 u1 info[attribute_length];
465 *******************************************************************************/
467 bool loader_skip_attribute_body(classbuffer *cb)
471 if (!suck_check_classbuffer_size(cb, 4))
474 attribute_length = suck_u4(cb);
476 if (!suck_check_classbuffer_size(cb, attribute_length))
479 suck_skip_nbytes(cb, attribute_length);
485 /* load_constantpool ***********************************************************
487 Loads the constantpool of a class, the entries are transformed into
488 a simpler format by resolving references (a detailed overview of
489 the compact structures can be found in global.h).
491 *******************************************************************************/
493 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
496 /* The following structures are used to save information which cannot be
497 processed during the first pass. After the complete constantpool has
498 been traversed the references can be resolved.
499 (only in specific order) */
501 /* CONSTANT_Class entries */
502 typedef struct forward_class {
503 struct forward_class *next;
508 /* CONSTANT_String */
509 typedef struct forward_string {
510 struct forward_string *next;
515 /* CONSTANT_NameAndType */
516 typedef struct forward_nameandtype {
517 struct forward_nameandtype *next;
521 } forward_nameandtype;
523 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
524 typedef struct forward_fieldmethint {
525 struct forward_fieldmethint *next;
529 u2 nameandtype_index;
530 } forward_fieldmethint;
536 forward_class *forward_classes = NULL;
537 forward_string *forward_strings = NULL;
538 forward_nameandtype *forward_nameandtypes = NULL;
539 forward_fieldmethint *forward_fieldmethints = NULL;
543 forward_nameandtype *nfn;
544 forward_fieldmethint *nff;
552 /* number of entries in the constant_pool table plus one */
553 if (!suck_check_classbuffer_size(cb, 2))
556 cpcount = c->cpcount = suck_u2(cb);
558 /* allocate memory */
559 cptags = c->cptags = MNEW(u1, cpcount);
560 cpinfos = c->cpinfos = MNEW(void*, cpcount);
563 exceptions_throw_classformaterror(c, "Illegal constant pool size");
567 #if defined(ENABLE_STATISTICS)
569 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
572 /* initialize constantpool */
573 for (idx = 0; idx < cpcount; idx++) {
574 cptags[idx] = CONSTANT_UNUSED;
579 /******* first pass *******/
580 /* entries which cannot be resolved now are written into
581 temporary structures and traversed again later */
584 while (idx < cpcount) {
587 /* get constant type */
588 if (!suck_check_classbuffer_size(cb, 1))
596 nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
598 nfc->next = forward_classes;
599 forward_classes = nfc;
601 nfc->thisindex = idx;
602 /* reference to CONSTANT_NameAndType */
603 if (!suck_check_classbuffer_size(cb, 2))
606 nfc->name_index = suck_u2(cb);
611 case CONSTANT_String:
613 nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
615 nfs->next = forward_strings;
616 forward_strings = nfs;
618 nfs->thisindex = idx;
620 /* reference to CONSTANT_Utf8_info with string characters */
621 if (!suck_check_classbuffer_size(cb, 2))
624 nfs->string_index = suck_u2(cb);
629 case CONSTANT_NameAndType:
631 nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
633 nfn->next = forward_nameandtypes;
634 forward_nameandtypes = nfn;
636 nfn->thisindex = idx;
638 if (!suck_check_classbuffer_size(cb, 2 + 2))
641 /* reference to CONSTANT_Utf8_info containing simple name */
642 nfn->name_index = suck_u2(cb);
644 /* reference to CONSTANT_Utf8_info containing field or method
646 nfn->sig_index = suck_u2(cb);
651 case CONSTANT_Fieldref:
652 case CONSTANT_Methodref:
653 case CONSTANT_InterfaceMethodref:
655 nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
657 nff->next = forward_fieldmethints;
658 forward_fieldmethints = nff;
660 nff->thisindex = idx;
664 if (!suck_check_classbuffer_size(cb, 2 + 2))
667 /* class or interface type that contains the declaration of the
669 nff->class_index = suck_u2(cb);
671 /* name and descriptor of the field or method */
672 nff->nameandtype_index = suck_u2(cb);
677 case CONSTANT_Integer: {
678 constant_integer *ci = NEW(constant_integer);
680 #if defined(ENABLE_STATISTICS)
682 count_const_pool_len += sizeof(constant_integer);
685 if (!suck_check_classbuffer_size(cb, 4))
688 ci->value = suck_s4(cb);
689 cptags[idx] = CONSTANT_Integer;
696 case CONSTANT_Float: {
697 constant_float *cf = NEW(constant_float);
699 #if defined(ENABLE_STATISTICS)
701 count_const_pool_len += sizeof(constant_float);
704 if (!suck_check_classbuffer_size(cb, 4))
707 cf->value = suck_float(cb);
708 cptags[idx] = CONSTANT_Float;
715 case CONSTANT_Long: {
716 constant_long *cl = NEW(constant_long);
718 #if defined(ENABLE_STATISTICS)
720 count_const_pool_len += sizeof(constant_long);
723 if (!suck_check_classbuffer_size(cb, 8))
726 cl->value = suck_s8(cb);
727 cptags[idx] = CONSTANT_Long;
731 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
737 case CONSTANT_Double: {
738 constant_double *cd = NEW(constant_double);
740 #if defined(ENABLE_STATISTICS)
742 count_const_pool_len += sizeof(constant_double);
745 if (!suck_check_classbuffer_size(cb, 8))
748 cd->value = suck_double(cb);
749 cptags[idx] = CONSTANT_Double;
753 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
759 case CONSTANT_Utf8: {
762 /* number of bytes in the bytes array (not string-length) */
763 if (!suck_check_classbuffer_size(cb, 2))
766 length = suck_u2(cb);
767 cptags[idx] = CONSTANT_Utf8;
769 /* validate the string */
770 if (!suck_check_classbuffer_size(cb, length))
773 #ifdef ENABLE_VERIFIER
775 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
777 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
780 #endif /* ENABLE_VERIFIER */
781 /* insert utf-string into the utf-symboltable */
782 cpinfos[idx] = utf_new((char *) cb->pos, length);
784 /* skip bytes of the string (buffer size check above) */
785 suck_skip_nbytes(cb, length);
791 exceptions_throw_classformaterror(c, "Illegal constant pool type");
797 /* resolve entries in temporary structures */
799 while (forward_classes) {
800 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
804 #ifdef ENABLE_VERIFIER
805 if (opt_verify && !is_valid_name_utf(name)) {
806 exceptions_throw_classformaterror(c, "Class reference with invalid name");
809 #endif /* ENABLE_VERIFIER */
811 /* add all class references to the descriptor_pool */
813 if (!descriptor_pool_add_class(descpool, name))
816 cptags[forward_classes->thisindex] = CONSTANT_Class;
818 /* the classref is created later */
819 cpinfos[forward_classes->thisindex] = name;
821 nfc = forward_classes;
822 forward_classes = forward_classes->next;
825 while (forward_strings) {
826 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
831 /* resolve utf-string */
832 cptags[forward_strings->thisindex] = CONSTANT_String;
833 cpinfos[forward_strings->thisindex] = text;
835 nfs = forward_strings;
836 forward_strings = forward_strings->next;
839 while (forward_nameandtypes) {
840 constant_nameandtype *cn = NEW(constant_nameandtype);
842 #if defined(ENABLE_STATISTICS)
844 count_const_pool_len += sizeof(constant_nameandtype);
847 /* resolve simple name and descriptor */
848 cn->name = (utf*) class_getconstant(c,
849 forward_nameandtypes->name_index,
854 cn->descriptor = (utf*) class_getconstant(c,
855 forward_nameandtypes->sig_index,
860 #ifdef ENABLE_VERIFIER
863 if (!is_valid_name_utf(cn->name)) {
864 exceptions_throw_classformaterror(c,
865 "Illegal Field name \"%s\"",
871 /* disallow referencing <clinit> among others */
872 if (cn->name->text[0] == '<' && cn->name != utf_init) {
873 exceptions_throw_classformaterror(c, "Illegal reference to special method");
877 #endif /* ENABLE_VERIFIER */
879 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
880 cpinfos[forward_nameandtypes->thisindex] = cn;
882 nfn = forward_nameandtypes;
883 forward_nameandtypes = forward_nameandtypes->next;
886 while (forward_fieldmethints) {
887 constant_nameandtype *nat;
888 constant_FMIref *fmi = NEW(constant_FMIref);
890 #if defined(ENABLE_STATISTICS)
892 count_const_pool_len += sizeof(constant_FMIref);
894 /* resolve simple name and descriptor */
896 nat = (constant_nameandtype*) class_getconstant(c,
897 forward_fieldmethints->nameandtype_index,
898 CONSTANT_NameAndType);
903 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
905 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
908 /* the classref is created later */
910 fmi->p.index = forward_fieldmethints->class_index;
911 fmi->name = nat->name;
912 fmi->descriptor = nat->descriptor;
914 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
915 cpinfos[forward_fieldmethints->thisindex] = fmi;
917 nff = forward_fieldmethints;
918 forward_fieldmethints = forward_fieldmethints->next;
921 /* everything was ok */
927 /* loader_load_attribute_signature *********************************************
929 Signature_attribute {
930 u2 attribute_name_index;
935 *******************************************************************************/
937 #if defined(ENABLE_JAVASE)
938 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
948 /* check remaining bytecode */
950 if (!suck_check_classbuffer_size(cb, 4 + 2))
953 /* check attribute length */
955 attribute_length = suck_u4(cb);
957 if (attribute_length != 2) {
958 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
962 if (*signature != NULL) {
963 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
969 signature_index = suck_u2(cb);
971 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
973 if (*signature == NULL)
978 #endif /* defined(ENABLE_JAVASE) */
981 /* load_class_from_sysloader ***************************************************
983 Load the class with the given name using the system class loader
986 name.............the classname
990 NULL if an exception has been thrown
992 *******************************************************************************/
994 classinfo *load_class_from_sysloader(utf *name)
1001 assert(class_java_lang_Object);
1002 assert(class_java_lang_ClassLoader);
1003 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1005 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1006 utf_getSystemClassLoader,
1007 utf_void__java_lang_ClassLoader,
1008 class_java_lang_Object,
1014 clo = vm_call_method(m, NULL);
1019 cl = loader_hashtable_classloader_add(clo);
1021 c = load_class_from_classloader(name, cl);
1027 /* load_class_from_classloader *************************************************
1029 Load the class with the given name using the given user-defined class loader.
1032 name.............the classname
1033 cl...............user-defined class loader
1036 the loaded class, or
1037 NULL if an exception has been thrown
1039 *******************************************************************************/
1041 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1046 java_handle_t *string;
1047 #if defined(ENABLE_RT_TIMING)
1048 struct timespec time_start, time_lookup, time_prepare, time_java,
1052 RT_TIMING_GET_TIME(time_start);
1056 /* lookup if this class has already been loaded */
1058 c = classcache_lookup(cl, name);
1060 RT_TIMING_GET_TIME(time_lookup);
1061 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1066 /* if other class loader than bootstrap, call it */
1074 namelen = name->blength;
1076 /* handle array classes */
1077 if (text[0] == '[') {
1083 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1084 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1085 exceptions_throw_classnotfoundexception(name);
1089 u = utf_new(text + 2, namelen - 3);
1091 if (!(comp = load_class_from_classloader(u, cl)))
1094 /* create the array class */
1096 c = class_array_of(comp, false);
1098 tmpc = classcache_store(cl, c, true);
1101 /* exception, free the loaded class */
1102 c->state &= ~CLASS_LOADING;
1109 /* load the component class */
1111 u = utf_new(text + 1, namelen - 1);
1113 if (!(comp = load_class_from_classloader(u, cl)))
1116 /* create the array class */
1118 c = class_array_of(comp, false);
1120 tmpc = classcache_store(cl, c, true);
1123 /* exception, free the loaded class */
1124 c->state &= ~CLASS_LOADING;
1131 /* primitive array classes are loaded by the bootstrap loader */
1133 c = load_class_bootstrap(name);
1139 LLNI_class_get(cl, c);
1141 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1142 /* OpenJDK uses this internal function because it's
1145 lc = class_resolveclassmethod(c,
1146 utf_loadClassInternal,
1147 utf_java_lang_String__java_lang_Class,
1151 lc = class_resolveclassmethod(c,
1153 utf_java_lang_String__java_lang_Class,
1159 return false; /* exception */
1161 /* move return value into `o' and cast it afterwards to a classinfo* */
1163 string = javastring_new_slash_to_dot(name);
1165 RT_TIMING_GET_TIME(time_prepare);
1167 o = vm_call_method(lc, (java_handle_t *) cl, string);
1169 RT_TIMING_GET_TIME(time_java);
1171 c = LLNI_classinfo_unwrap(o);
1174 /* Store this class in the loaded class cache. If another
1175 class with the same (initloader,name) pair has been
1176 stored earlier it will be returned by classcache_store
1177 In this case classcache_store may not free the class
1178 because it has already been exposed to Java code which
1179 may have kept references to that class. */
1181 tmpc = classcache_store(cl, c, false);
1184 /* exception, free the loaded class */
1185 c->state &= ~CLASS_LOADING;
1192 RT_TIMING_GET_TIME(time_cache);
1194 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1195 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1196 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1198 /* SUN compatible -verbose:class output */
1200 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1202 utf_display_printable_ascii_classname(name);
1206 #if defined(ENABLE_JVMTI)
1207 /* fire Class Load JVMTI event */
1208 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1215 c = load_class_bootstrap(name);
1221 /* load_class_bootstrap ********************************************************
1223 Load the class with the given name using the bootstrap class loader.
1226 name.............the classname
1229 loaded classinfo, or
1230 NULL if an exception has been thrown
1233 load_class_bootstrap is synchronized. It can be treated as an
1236 *******************************************************************************/
1238 classinfo *load_class_bootstrap(utf *name)
1243 #if defined(ENABLE_RT_TIMING)
1244 struct timespec time_start, time_lookup, time_array, time_suck,
1245 time_load, time_cache;
1248 RT_TIMING_GET_TIME(time_start);
1254 /* lookup if this class has already been loaded */
1256 r = classcache_lookup(NULL, name);
1259 RT_TIMING_GET_TIME(time_lookup);
1260 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1265 RT_TIMING_GET_TIME(time_lookup);
1266 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1268 /* create the classinfo */
1270 c = class_create_classinfo(name);
1272 /* handle array classes */
1274 if (name->text[0] == '[') {
1275 c = load_newly_created_array(c, NULL);
1280 assert(c->state & CLASS_LOADED);
1282 RT_TIMING_GET_TIME(time_array);
1283 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1288 #if defined(ENABLE_STATISTICS)
1291 if (opt_getcompilingtime)
1292 compilingtime_stop();
1294 if (opt_getloadingtime)
1295 loadingtime_start();
1298 /* load classdata, throw exception on error */
1303 exceptions_throw_classnotfoundexception(name);
1307 RT_TIMING_GET_TIME(time_suck);
1309 /* load the class from the buffer */
1311 r = load_class_from_classbuffer(cb);
1313 RT_TIMING_GET_TIME(time_load);
1316 /* the class could not be loaded, free the classinfo struct */
1321 /* Store this class in the loaded class cache this step also
1322 checks the loading constraints. If the class has been
1323 loaded before, the earlier loaded class is returned. */
1325 classinfo *res = classcache_store(NULL, c, true);
1332 // Add the package name to the boot packages.
1333 Package::add(c->packagename);
1339 RT_TIMING_GET_TIME(time_cache);
1341 /* SUN compatible -verbose:class output */
1343 if (opt_verboseclass && r) {
1345 utf_display_printable_ascii_classname(name);
1346 printf(" from %s]\n", cb->path);
1353 #if defined(ENABLE_STATISTICS)
1356 if (opt_getloadingtime)
1359 if (opt_getcompilingtime)
1360 compilingtime_start();
1363 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1364 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1365 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1366 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1372 /* load_class_from_classbuffer_intern ******************************************
1374 Loads a class from a classbuffer into a given classinfo structure.
1375 Super-classes are also loaded at this point and some verfication
1379 This function is NOT synchronized!
1381 *******************************************************************************/
1383 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1389 utf **interfacesnames;
1391 constant_classref *cr;
1395 descriptor_pool *descpool;
1396 #if defined(ENABLE_STATISTICS)
1400 #if defined(ENABLE_RT_TIMING)
1401 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1402 time_setup, time_fields, time_methods, time_classrefs,
1403 time_descs, time_setrefs, time_parsefds, time_parsemds,
1404 time_parsecpool, time_verify, time_attrs;
1407 // Create new dump memory area.
1410 RT_TIMING_GET_TIME(time_start);
1412 /* Get the classbuffer's class. */
1416 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1419 /* check signature */
1421 if (suck_u4(cb) != MAGIC) {
1422 exceptions_throw_classformaterror(c, "Bad magic number");
1431 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1432 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1436 RT_TIMING_GET_TIME(time_checks);
1438 /* create a new descriptor pool */
1440 descpool = descriptor_pool_new(c);
1442 RT_TIMING_GET_TIME(time_ndpool);
1444 /* load the constant pool */
1446 if (!load_constantpool(cb, descpool))
1449 RT_TIMING_GET_TIME(time_cpool);
1453 if (!suck_check_classbuffer_size(cb, 2))
1456 /* We OR the flags here, as we set already some flags in
1457 class_create_classinfo. */
1459 c->flags |= suck_u2(cb);
1461 /* check ACC flags consistency */
1463 if (c->flags & ACC_INTERFACE) {
1464 if (!(c->flags & ACC_ABSTRACT)) {
1465 /* We work around this because interfaces in JDK 1.1 are
1466 * not declared abstract. */
1468 c->flags |= ACC_ABSTRACT;
1471 if (c->flags & ACC_FINAL) {
1472 exceptions_throw_classformaterror(c,
1473 "Illegal class modifiers: 0x%X",
1478 if (c->flags & ACC_SUPER) {
1479 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1483 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1484 exceptions_throw_classformaterror(c,
1485 "Illegal class modifiers: 0x%X",
1490 if (!suck_check_classbuffer_size(cb, 2 + 2))
1495 index = suck_u2(cb);
1497 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1502 if (c->name == utf_not_named_yet) {
1503 /* we finally have a name for this class */
1505 class_set_packagename(c);
1507 else if (name != c->name) {
1508 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1512 /* Retrieve superclass. */
1516 index = suck_u2(cb);
1521 /* This is only allowed for java.lang.Object. */
1523 if (c->name != utf_java_lang_Object) {
1524 exceptions_throw_classformaterror(c, "Bad superclass index");
1529 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1531 if (supername == NULL)
1534 /* java.lang.Object may not have a super class. */
1536 if (c->name == utf_java_lang_Object) {
1537 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1541 /* Detect circularity. */
1543 if (supername == c->name) {
1544 exceptions_throw_classcircularityerror(c);
1548 /* Interfaces must have java.lang.Object as super class. */
1550 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1551 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1556 /* Parse the super interfaces. */
1558 if (!suck_check_classbuffer_size(cb, 2))
1561 c->interfacescount = suck_u2(cb);
1563 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1566 c->interfaces = MNEW(classinfo*, c->interfacescount);
1568 /* Get the names of the super interfaces. */
1570 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1572 for (int32_t i = 0; i < c->interfacescount; i++) {
1573 index = suck_u2(cb);
1575 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1580 interfacesnames[i] = u;
1583 RT_TIMING_GET_TIME(time_setup);
1587 if (!suck_check_classbuffer_size(cb, 2))
1590 c->fieldscount = suck_u2(cb);
1591 c->fields = MNEW(fieldinfo, c->fieldscount);
1593 MZERO(c->fields, fieldinfo, c->fieldscount);
1595 for (int32_t i = 0; i < c->fieldscount; i++) {
1596 if (!field_load(cb, &(c->fields[i]), descpool))
1600 RT_TIMING_GET_TIME(time_fields);
1602 /* Parse methods. */
1604 if (!suck_check_classbuffer_size(cb, 2))
1607 c->methodscount = suck_u2(cb);
1608 c->methods = MNEW(methodinfo, c->methodscount);
1610 MZERO(c->methods, methodinfo, c->methodscount);
1612 for (int32_t i = 0; i < c->methodscount; i++) {
1613 if (!method_load(cb, &(c->methods[i]), descpool))
1617 RT_TIMING_GET_TIME(time_methods);
1619 /* create the class reference table */
1622 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1624 RT_TIMING_GET_TIME(time_classrefs);
1626 /* allocate space for the parsed descriptors */
1628 descriptor_pool_alloc_parsed_descriptors(descpool);
1629 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1631 #if defined(ENABLE_STATISTICS)
1633 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1634 count_classref_len += classrefsize;
1635 count_parsed_desc_len += descsize;
1639 RT_TIMING_GET_TIME(time_descs);
1641 /* put the classrefs in the constant pool */
1643 for (int32_t i = 0; i < c->cpcount; i++) {
1644 if (c->cptags[i] == CONSTANT_Class) {
1645 utf *name = (utf *) c->cpinfos[i];
1646 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1650 /* Resolve the super class. */
1652 if (supername != NULL) {
1653 cr = descriptor_pool_lookup_classref(descpool, supername);
1658 /* XXX This should be done better. */
1659 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1662 resolve_handle_pending_exception(true);
1666 /* Interfaces are not allowed as super classes. */
1668 if (tc->flags & ACC_INTERFACE) {
1669 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1673 /* Don't allow extending final classes */
1675 if (tc->flags & ACC_FINAL) {
1676 exceptions_throw_verifyerror(NULL,
1677 "Cannot inherit from final class");
1681 /* Store the super class. */
1686 /* Resolve the super interfaces. */
1688 for (int32_t i = 0; i < c->interfacescount; i++) {
1689 u = interfacesnames[i];
1690 cr = descriptor_pool_lookup_classref(descpool, u);
1695 /* XXX This should be done better. */
1696 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1699 resolve_handle_pending_exception(true);
1703 /* Detect circularity. */
1706 exceptions_throw_classcircularityerror(c);
1710 if (!(tc->flags & ACC_INTERFACE)) {
1711 exceptions_throw_incompatibleclasschangeerror(tc,
1712 "Implementing class");
1716 /* Store the super interface. */
1718 c->interfaces[i] = tc;
1721 RT_TIMING_GET_TIME(time_setrefs);
1723 /* Parse the field descriptors. */
1725 for (int32_t i = 0; i < c->fieldscount; i++) {
1726 c->fields[i].parseddesc =
1727 descriptor_pool_parse_field_descriptor(descpool,
1728 c->fields[i].descriptor);
1729 if (!c->fields[i].parseddesc)
1733 RT_TIMING_GET_TIME(time_parsefds);
1735 /* parse method descriptors */
1737 for (int32_t i = 0; i < c->methodscount; i++) {
1738 methodinfo *m = &c->methods[i];
1740 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1741 m->flags, class_get_self_classref(m->clazz));
1745 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1746 if (!m->rawexceptiontable[j].catchtype.any)
1749 if ((m->rawexceptiontable[j].catchtype.ref =
1750 descriptor_pool_lookup_classref(descpool,
1751 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1755 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1756 if (!m->thrownexceptions[j].any)
1759 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1760 (utf *) m->thrownexceptions[j].any)) == NULL)
1765 RT_TIMING_GET_TIME(time_parsemds);
1767 /* parse the loaded descriptors */
1769 for (int32_t i = 0; i < c->cpcount; i++) {
1770 constant_FMIref *fmi;
1773 switch (c->cptags[i]) {
1774 case CONSTANT_Fieldref:
1775 fmi = (constant_FMIref *) c->cpinfos[i];
1776 fmi->parseddesc.fd =
1777 descriptor_pool_parse_field_descriptor(descpool,
1779 if (!fmi->parseddesc.fd)
1782 index = fmi->p.index;
1784 (constant_classref *) class_getconstant(c, index,
1786 if (!fmi->p.classref)
1789 case CONSTANT_Methodref:
1790 case CONSTANT_InterfaceMethodref:
1791 fmi = (constant_FMIref *) c->cpinfos[i];
1792 index = fmi->p.index;
1794 (constant_classref *) class_getconstant(c, index,
1796 if (!fmi->p.classref)
1798 fmi->parseddesc.md =
1799 descriptor_pool_parse_method_descriptor(descpool,
1803 if (!fmi->parseddesc.md)
1809 RT_TIMING_GET_TIME(time_parsecpool);
1811 #ifdef ENABLE_VERIFIER
1812 /* Check if all fields and methods can be uniquely
1813 * identified by (name,descriptor). */
1816 /* We use a hash table here to avoid making the
1817 * average case quadratic in # of methods, fields.
1819 static int shift = 0;
1821 u2 *next; /* for chaining colliding hash entries */
1827 /* Allocate hashtable */
1828 len = c->methodscount;
1829 if (len < c->fieldscount) len = c->fieldscount;
1831 hashtab = MNEW(u2,(hashlen + len));
1832 next = hashtab + hashlen;
1834 /* Determine bitshift (to get good hash values) */
1844 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1846 for (int32_t i = 0; i < c->fieldscount; ++i) {
1847 fieldinfo *fi = c->fields + i;
1849 /* It's ok if we lose bits here */
1850 index = ((((size_t) fi->name) +
1851 ((size_t) fi->descriptor)) >> shift) % hashlen;
1853 if ((old = hashtab[index])) {
1857 if (c->fields[old].name == fi->name &&
1858 c->fields[old].descriptor == fi->descriptor) {
1859 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1862 } while ((old = next[old]));
1864 hashtab[index] = i + 1;
1868 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1870 for (int32_t i = 0; i < c->methodscount; ++i) {
1871 methodinfo *mi = c->methods + i;
1873 /* It's ok if we lose bits here */
1874 index = ((((size_t) mi->name) +
1875 ((size_t) mi->descriptor)) >> shift) % hashlen;
1877 if ((old = hashtab[index])) {
1881 if (c->methods[old].name == mi->name &&
1882 c->methods[old].descriptor == mi->descriptor) {
1883 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1886 } while ((old = next[old]));
1888 hashtab[index] = i + 1;
1891 MFREE(hashtab, u2, (hashlen + len));
1893 #endif /* ENABLE_VERIFIER */
1895 RT_TIMING_GET_TIME(time_verify);
1897 #if defined(ENABLE_STATISTICS)
1899 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1900 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1901 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1905 /* load attribute structures */
1907 if (!class_load_attributes(cb))
1910 /* Pre Java 1.5 version don't check this. This implementation is
1911 like Java 1.5 do it: for class file version 45.3 we don't check
1912 it, older versions are checked. */
1914 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1915 /* check if all data has been read */
1916 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1918 if (classdata_left > 0) {
1919 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1924 RT_TIMING_GET_TIME(time_attrs);
1926 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1927 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1928 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1929 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1930 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1931 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1932 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1933 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1934 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1935 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1936 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1937 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1938 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1939 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1940 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1946 /* load_class_from_classbuffer *************************************************
1948 Convenience wrapper for load_class_from_classbuffer.
1951 This function is NOT synchronized!
1953 *******************************************************************************/
1955 classinfo *load_class_from_classbuffer(classbuffer *cb)
1960 /* Get the classbuffer's class. */
1964 /* Check if the class is already loaded. */
1966 if (c->state & CLASS_LOADED)
1969 #if defined(ENABLE_STATISTICS)
1971 count_class_loads++;
1974 #if !defined(NDEBUG)
1976 log_message_class("Loading class: ", c);
1979 /* Class is currently loading. */
1981 c->state |= CLASS_LOADING;
1983 /* Parse the classbuffer. */
1985 result = load_class_from_classbuffer_intern(cb);
1987 /* An error occurred. */
1989 if (result == false) {
1990 /* Revert loading state. */
1992 c->state = (c->state & ~CLASS_LOADING);
1997 /* Revert loading state and set loaded. */
1999 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2001 #if defined(ENABLE_JVMTI)
2002 /* fire Class Prepare JVMTI event */
2005 jvmti_ClassLoadPrepare(true, c);
2008 #if !defined(NDEBUG)
2010 log_message_class("Loading done class: ", c);
2017 /* load_newly_created_array ****************************************************
2019 Load a newly created array class.
2022 c....................the array class C has been loaded
2023 other classinfo......the array class was found in the class cache,
2025 NULL.................an exception has been thrown
2028 This is an internal function. Do not use it unless you know exactly
2031 Use one of the load_class_... functions for general array class loading.
2033 *******************************************************************************/
2035 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2037 classinfo *comp = NULL;
2039 methoddesc *clonedesc;
2040 constant_classref *classrefs;
2045 text = c->name->text;
2046 namelen = c->name->blength;
2048 /* Check array class name */
2050 if ((namelen < 2) || (text[0] != '[')) {
2051 exceptions_throw_classnotfoundexception(c->name);
2055 /* Check the element type */
2059 /* c is an array of arrays. We have to create the component class. */
2061 u = utf_new(text + 1, namelen - 1);
2063 comp = load_class_from_classloader(u, loader);
2068 assert(comp->state & CLASS_LOADED);
2070 /* the array's flags are that of the component class */
2071 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2072 c->classloader = comp->classloader;
2076 /* c is an array of objects. */
2078 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2079 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2080 exceptions_throw_classnotfoundexception(c->name);
2084 u = utf_new(text + 2, namelen - 3);
2086 if (!(comp = load_class_from_classloader(u, loader)))
2089 assert(comp->state & CLASS_LOADED);
2091 /* the array's flags are that of the component class */
2092 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2093 c->classloader = comp->classloader;
2097 /* c is an array of a primitive type */
2099 /* check for cases like `[II' and whether the character is a
2100 valid primitive type */
2102 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2103 exceptions_throw_classnotfoundexception(c->name);
2107 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2108 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2109 c->classloader = NULL;
2112 assert(class_java_lang_Object);
2113 #if defined(ENABLE_JAVASE)
2114 assert(class_java_lang_Cloneable);
2115 assert(class_java_io_Serializable);
2118 /* Setup the array class. */
2120 c->super = class_java_lang_Object;
2122 #if defined(ENABLE_JAVASE)
2124 c->interfacescount = 2;
2125 c->interfaces = MNEW(classinfo*, 2);
2126 c->interfaces[0] = class_java_lang_Cloneable;
2127 c->interfaces[1] = class_java_io_Serializable;
2129 #elif defined(ENABLE_JAVAME_CLDC1_1)
2131 c->interfacescount = 0;
2132 c->interfaces = NULL;
2135 # error unknow Java configuration
2138 c->methodscount = 1;
2139 c->methods = MNEW(methodinfo, c->methodscount);
2141 MZERO(c->methods, methodinfo, c->methodscount);
2143 classrefs = MNEW(constant_classref, 2);
2145 CLASSREF_INIT(classrefs[0], c, c->name);
2146 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2148 /* create descriptor for clone method */
2149 /* we need one paramslot which is reserved for the 'this' parameter */
2150 clonedesc = NEW(methoddesc);
2151 clonedesc->returntype.type = TYPE_ADR;
2152 clonedesc->returntype.classref = classrefs + 1;
2153 clonedesc->returntype.arraydim = 0;
2154 /* initialize params to "empty", add real params below in
2155 descriptor_params_from_paramtypes */
2156 clonedesc->paramcount = 0;
2157 clonedesc->paramslots = 0;
2158 clonedesc->paramtypes[0].classref = classrefs + 0;
2159 clonedesc->params = NULL;
2161 /* create methodinfo */
2164 MSET(clone, 0, methodinfo, 1);
2166 /* ATTENTION: if you delete the ACC_NATIVE below, set
2167 clone->maxlocals=1 (interpreter related) */
2169 clone->mutex = new Mutex();
2170 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2171 clone->name = utf_clone;
2172 clone->descriptor = utf_void__java_lang_Object;
2173 clone->parseddesc = clonedesc;
2176 /* parse the descriptor to get the register allocation */
2178 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2181 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2183 /* XXX: field: length? */
2185 /* array classes are not loaded from class files */
2187 c->state |= CLASS_LOADED;
2188 c->parseddescs = (u1 *) clonedesc;
2189 c->parseddescsize = sizeof(methodinfo);
2190 c->classrefs = classrefs;
2191 c->classrefcount = 1;
2193 /* insert class into the loaded class cache */
2194 /* XXX free classinfo if NULL returned? */
2196 return classcache_store(loader, c, true);
2200 /* loader_close ****************************************************************
2202 Frees all resources.
2204 *******************************************************************************/
2206 void loader_close(void)
2213 * These are local overrides for various environment variables in Emacs.
2214 * Please do not remove this and leave it at the end of the file, where
2215 * Emacs will automagically detect them.
2216 * ---------------------------------------------------------------------
2219 * indent-tabs-mode: t
2223 * vim:noexpandtab:sw=4:ts=4: