1 /* src/vmcore/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: loader.c 7921 2007-05-20 23:14:11Z michi $
38 #include "mm/memory.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit_interface.h"
53 #if defined(ENABLE_JAVASE)
54 # include "vmcore/annotation.h"
55 # include "vmcore/stackmap.h"
58 #include "vmcore/classcache.h"
59 #include "vmcore/linker.h"
60 #include "vmcore/loader.h"
61 #include "vmcore/options.h"
62 #include "vmcore/rt-timing.h"
64 #if defined(ENABLE_STATISTICS)
65 # include "vmcore/statistics.h"
68 #include "vmcore/suck.h"
70 #if defined(ENABLE_ZLIB)
71 # include "vmcore/zip.h"
74 #if defined(ENABLE_JVMTI)
75 # include "native/jvmti/cacaodbg.h"
79 /* global variables ***********************************************************/
81 static hashtable *hashtable_classloader;
84 /* loader_init *****************************************************************
86 Initializes all lists and loads all classes required for the system
89 *******************************************************************************/
91 bool loader_init(void)
93 #if defined(ENABLE_THREADS)
94 list_classpath_entry *lce;
96 /* Initialize the monitor pointer for zip/jar file locking. */
98 for (lce = list_first(list_classpath_entries); lce != NULL;
99 lce = list_next(list_classpath_entries, lce))
100 if (lce->type == CLASSPATH_ARCHIVE)
101 LOCK_INIT_OBJECT_LOCK(lce);
104 /* initialize classloader hashtable, 10 entries should be enough */
106 hashtable_classloader = NEW(hashtable);
107 hashtable_create(hashtable_classloader, 10);
109 /* load some important classes */
111 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
114 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
117 #if defined(ENABLE_JAVASE)
118 if (!(class_java_lang_Cloneable =
119 load_class_bootstrap(utf_java_lang_Cloneable)))
122 if (!(class_java_io_Serializable =
123 load_class_bootstrap(utf_java_io_Serializable)))
127 /* load classes for wrapping primitive types */
129 #if defined(ENABLE_JAVASE)
130 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
134 if (!(class_java_lang_Boolean =
135 load_class_bootstrap(utf_java_lang_Boolean)))
138 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
141 if (!(class_java_lang_Character =
142 load_class_bootstrap(utf_java_lang_Character)))
145 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
148 if (!(class_java_lang_Integer =
149 load_class_bootstrap(utf_java_lang_Integer)))
152 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
155 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
158 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
162 /* load some other important classes */
164 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
167 #if defined(ENABLE_JAVASE)
168 if (!(class_java_lang_ClassLoader =
169 load_class_bootstrap(utf_java_lang_ClassLoader)))
172 if (!(class_java_lang_SecurityManager =
173 load_class_bootstrap(utf_java_lang_SecurityManager)))
177 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
180 if (!(class_java_lang_Thread =
181 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
184 #if defined(ENABLE_JAVASE)
185 if (!(class_java_lang_ThreadGroup =
186 load_class_bootstrap(utf_java_lang_ThreadGroup)))
190 #if defined(WITH_CLASSPATH_GNU)
191 if (!(class_java_lang_VMSystem =
192 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
196 if (!(class_java_lang_VMThread =
197 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
202 /* some classes which may be used more often */
204 #if defined(ENABLE_JAVASE)
205 if (!(class_java_lang_StackTraceElement =
206 load_class_bootstrap(utf_java_lang_StackTraceElement)))
209 if (!(class_java_lang_reflect_Constructor =
210 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
213 if (!(class_java_lang_reflect_Field =
214 load_class_bootstrap(utf_java_lang_reflect_Field)))
217 if (!(class_java_lang_reflect_Method =
218 load_class_bootstrap(utf_java_lang_reflect_Method)))
221 if (!(class_java_security_PrivilegedAction =
222 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
225 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
228 if (!(arrayclass_java_lang_Object =
229 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
237 /* loader_hashtable_classloader_add ********************************************
239 Adds an entry to the classloader hashtable.
241 REMEMBER: Also use this to register native loaders!
243 *******************************************************************************/
245 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
247 hashtable_classloader_entry *cle;
254 LOCK_MONITOR_ENTER(hashtable_classloader->header);
256 /* key for entry is the hashcode of the classloader;
257 aligned to 16-byte boundaries */
259 #if defined(ENABLE_GC_CACAO)
260 key = heap_get_hashcode(cl) >> 4;
262 key = ((u4) (ptrint) cl) >> 4;
265 slot = key & (hashtable_classloader->size - 1);
266 cle = hashtable_classloader->ptr[slot];
268 /* search hashchain for existing entry */
269 /* XXX no GC collection is allowed here, make this a critical section */
272 if (cle->object == cl)
278 /* if no classloader was found, we create a new entry here */
281 cle = NEW(hashtable_classloader_entry);
283 #if defined(ENABLE_GC_CACAO)
284 /* register the classloader object with the GC */
286 gc_reference_register(&(cle->object));
291 /* insert entry into hashtable */
293 cle->hashlink = hashtable_classloader->ptr[slot];
294 hashtable_classloader->ptr[slot] = cle;
296 /* update number of entries */
298 hashtable_classloader->entries++;
302 LOCK_MONITOR_EXIT(hashtable_classloader->header);
308 /* loader_hashtable_classloader_find *******************************************
310 Find an entry in the classloader hashtable.
312 *******************************************************************************/
314 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
316 hashtable_classloader_entry *cle;
323 /* key for entry is the hashcode of the classloader;
324 aligned to 16-byte boundaries */
326 #if defined(ENABLE_GC_CACAO)
327 key = heap_get_hashcode(cl) >> 4;
329 key = ((u4) (ptrint) cl) >> 4;
332 slot = key & (hashtable_classloader->size - 1);
333 cle = hashtable_classloader->ptr[slot];
335 /* search hashchain for existing entry */
336 /* XXX no GC collection is allowed here, make this a critical section */
339 if (cle->object == cl)
349 /* loader_load_all_classes *****************************************************
351 Loads all classes specified in the BOOTCLASSPATH.
353 *******************************************************************************/
355 void loader_load_all_classes(void)
357 list_classpath_entry *lce;
358 #if defined(ENABLE_ZLIB)
361 hashtable_zipfile_entry *htzfe;
365 for (lce = list_first(list_classpath_entries); lce != NULL;
366 lce = list_next(list_classpath_entries, lce)) {
367 #if defined(ENABLE_ZLIB)
368 if (lce->type == CLASSPATH_ARCHIVE) {
369 /* get the classes hashtable */
373 for (slot = 0; slot < ht->size; slot++) {
374 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
376 for (; htzfe; htzfe = htzfe->hashlink) {
379 /* skip all entries in META-INF and .properties,
382 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
383 strstr(u->text, ".properties") ||
384 strstr(u->text, ".png"))
387 /* load class from bootstrap classloader */
389 if (!load_class_bootstrap(u)) {
390 fprintf(stderr, "Error loading: ");
391 utf_fprint_printable_ascii_classname(stderr, u);
392 fprintf(stderr, "\n");
395 /* print out exception and cause */
397 exceptions_print_current_exception();
405 #if defined(ENABLE_ZLIB)
412 /* loader_skip_attribute_body **************************************************
414 Skips an attribute the attribute_name_index has already been read.
417 u2 attribute_name_index;
419 u1 info[attribute_length];
422 *******************************************************************************/
424 bool loader_skip_attribute_body(classbuffer *cb)
428 if (!suck_check_classbuffer_size(cb, 4))
431 attribute_length = suck_u4(cb);
433 if (!suck_check_classbuffer_size(cb, attribute_length))
436 suck_skip_nbytes(cb, attribute_length);
442 /* load_constantpool ***********************************************************
444 Loads the constantpool of a class, the entries are transformed into
445 a simpler format by resolving references (a detailed overview of
446 the compact structures can be found in global.h).
448 *******************************************************************************/
450 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
453 /* The following structures are used to save information which cannot be
454 processed during the first pass. After the complete constantpool has
455 been traversed the references can be resolved.
456 (only in specific order) */
458 /* CONSTANT_Class entries */
459 typedef struct forward_class {
460 struct forward_class *next;
465 /* CONSTANT_String */
466 typedef struct forward_string {
467 struct forward_string *next;
472 /* CONSTANT_NameAndType */
473 typedef struct forward_nameandtype {
474 struct forward_nameandtype *next;
478 } forward_nameandtype;
480 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
481 typedef struct forward_fieldmethint {
482 struct forward_fieldmethint *next;
486 u2 nameandtype_index;
487 } forward_fieldmethint;
493 forward_class *forward_classes = NULL;
494 forward_string *forward_strings = NULL;
495 forward_nameandtype *forward_nameandtypes = NULL;
496 forward_fieldmethint *forward_fieldmethints = NULL;
500 forward_nameandtype *nfn;
501 forward_fieldmethint *nff;
509 /* number of entries in the constant_pool table plus one */
510 if (!suck_check_classbuffer_size(cb, 2))
513 cpcount = c->cpcount = suck_u2(cb);
515 /* allocate memory */
516 cptags = c->cptags = MNEW(u1, cpcount);
517 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
520 exceptions_throw_classformaterror(c, "Illegal constant pool size");
524 #if defined(ENABLE_STATISTICS)
526 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
529 /* initialize constantpool */
530 for (idx = 0; idx < cpcount; idx++) {
531 cptags[idx] = CONSTANT_UNUSED;
536 /******* first pass *******/
537 /* entries which cannot be resolved now are written into
538 temporary structures and traversed again later */
541 while (idx < cpcount) {
544 /* get constant type */
545 if (!suck_check_classbuffer_size(cb, 1))
552 nfc = DNEW(forward_class);
554 nfc->next = forward_classes;
555 forward_classes = nfc;
557 nfc->thisindex = idx;
558 /* reference to CONSTANT_NameAndType */
559 if (!suck_check_classbuffer_size(cb, 2))
562 nfc->name_index = suck_u2(cb);
567 case CONSTANT_String:
568 nfs = DNEW(forward_string);
570 nfs->next = forward_strings;
571 forward_strings = nfs;
573 nfs->thisindex = idx;
575 /* reference to CONSTANT_Utf8_info with string characters */
576 if (!suck_check_classbuffer_size(cb, 2))
579 nfs->string_index = suck_u2(cb);
584 case CONSTANT_NameAndType:
585 nfn = DNEW(forward_nameandtype);
587 nfn->next = forward_nameandtypes;
588 forward_nameandtypes = nfn;
590 nfn->thisindex = idx;
592 if (!suck_check_classbuffer_size(cb, 2 + 2))
595 /* reference to CONSTANT_Utf8_info containing simple name */
596 nfn->name_index = suck_u2(cb);
598 /* reference to CONSTANT_Utf8_info containing field or method
600 nfn->sig_index = suck_u2(cb);
605 case CONSTANT_Fieldref:
606 case CONSTANT_Methodref:
607 case CONSTANT_InterfaceMethodref:
608 nff = DNEW(forward_fieldmethint);
610 nff->next = forward_fieldmethints;
611 forward_fieldmethints = nff;
613 nff->thisindex = idx;
617 if (!suck_check_classbuffer_size(cb, 2 + 2))
620 /* class or interface type that contains the declaration of the
622 nff->class_index = suck_u2(cb);
624 /* name and descriptor of the field or method */
625 nff->nameandtype_index = suck_u2(cb);
630 case CONSTANT_Integer: {
631 constant_integer *ci = NEW(constant_integer);
633 #if defined(ENABLE_STATISTICS)
635 count_const_pool_len += sizeof(constant_integer);
638 if (!suck_check_classbuffer_size(cb, 4))
641 ci->value = suck_s4(cb);
642 cptags[idx] = CONSTANT_Integer;
649 case CONSTANT_Float: {
650 constant_float *cf = NEW(constant_float);
652 #if defined(ENABLE_STATISTICS)
654 count_const_pool_len += sizeof(constant_float);
657 if (!suck_check_classbuffer_size(cb, 4))
660 cf->value = suck_float(cb);
661 cptags[idx] = CONSTANT_Float;
668 case CONSTANT_Long: {
669 constant_long *cl = NEW(constant_long);
671 #if defined(ENABLE_STATISTICS)
673 count_const_pool_len += sizeof(constant_long);
676 if (!suck_check_classbuffer_size(cb, 8))
679 cl->value = suck_s8(cb);
680 cptags[idx] = CONSTANT_Long;
684 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
690 case CONSTANT_Double: {
691 constant_double *cd = NEW(constant_double);
693 #if defined(ENABLE_STATISTICS)
695 count_const_pool_len += sizeof(constant_double);
698 if (!suck_check_classbuffer_size(cb, 8))
701 cd->value = suck_double(cb);
702 cptags[idx] = CONSTANT_Double;
706 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
712 case CONSTANT_Utf8: {
715 /* number of bytes in the bytes array (not string-length) */
716 if (!suck_check_classbuffer_size(cb, 2))
719 length = suck_u2(cb);
720 cptags[idx] = CONSTANT_Utf8;
722 /* validate the string */
723 if (!suck_check_classbuffer_size(cb, length))
726 #ifdef ENABLE_VERIFIER
728 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
730 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
733 #endif /* ENABLE_VERIFIER */
734 /* insert utf-string into the utf-symboltable */
735 cpinfos[idx] = utf_new((char *) cb->pos, length);
737 /* skip bytes of the string (buffer size check above) */
738 suck_skip_nbytes(cb, length);
744 exceptions_throw_classformaterror(c, "Illegal constant pool type");
750 /* resolve entries in temporary structures */
752 while (forward_classes) {
754 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
758 #ifdef ENABLE_VERIFIER
759 if (opt_verify && !is_valid_name_utf(name)) {
760 exceptions_throw_classformaterror(c, "Class reference with invalid name");
763 #endif /* ENABLE_VERIFIER */
765 /* add all class references to the descriptor_pool */
767 if (!descriptor_pool_add_class(descpool, name))
770 cptags[forward_classes->thisindex] = CONSTANT_Class;
775 if (!(tc = load_class_bootstrap(name)))
778 /* link the class later, because we cannot link the class currently
780 list_add_first(&unlinkedclasses, tc);
783 /* the classref is created later */
784 cpinfos[forward_classes->thisindex] = name;
786 nfc = forward_classes;
787 forward_classes = forward_classes->next;
790 while (forward_strings) {
792 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
796 /* resolve utf-string */
797 cptags[forward_strings->thisindex] = CONSTANT_String;
798 cpinfos[forward_strings->thisindex] = text;
800 nfs = forward_strings;
801 forward_strings = forward_strings->next;
804 while (forward_nameandtypes) {
805 constant_nameandtype *cn = NEW(constant_nameandtype);
807 #if defined(ENABLE_STATISTICS)
809 count_const_pool_len += sizeof(constant_nameandtype);
812 /* resolve simple name and descriptor */
813 cn->name = class_getconstant(c,
814 forward_nameandtypes->name_index,
819 cn->descriptor = class_getconstant(c,
820 forward_nameandtypes->sig_index,
825 #ifdef ENABLE_VERIFIER
828 if (!is_valid_name_utf(cn->name)) {
829 exceptions_throw_classformaterror(c,
830 "Illegal Field name \"%s\"",
836 /* disallow referencing <clinit> among others */
837 if (cn->name->text[0] == '<' && cn->name != utf_init) {
838 exceptions_throw_classformaterror(c, "Illegal reference to special method");
842 #endif /* ENABLE_VERIFIER */
844 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
845 cpinfos[forward_nameandtypes->thisindex] = cn;
847 nfn = forward_nameandtypes;
848 forward_nameandtypes = forward_nameandtypes->next;
851 while (forward_fieldmethints) {
852 constant_nameandtype *nat;
853 constant_FMIref *fmi = NEW(constant_FMIref);
855 #if defined(ENABLE_STATISTICS)
857 count_const_pool_len += sizeof(constant_FMIref);
859 /* resolve simple name and descriptor */
861 nat = class_getconstant(c,
862 forward_fieldmethints->nameandtype_index,
863 CONSTANT_NameAndType);
867 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
869 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
872 /* the classref is created later */
874 fmi->p.index = forward_fieldmethints->class_index;
875 fmi->name = nat->name;
876 fmi->descriptor = nat->descriptor;
878 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
879 cpinfos[forward_fieldmethints->thisindex] = fmi;
881 nff = forward_fieldmethints;
882 forward_fieldmethints = forward_fieldmethints->next;
885 /* everything was ok */
891 /* loader_load_attribute_signature *********************************************
893 Signature_attribute {
894 u2 attribute_name_index;
899 *******************************************************************************/
901 #if defined(ENABLE_JAVASE)
902 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
912 /* check remaining bytecode */
914 if (!suck_check_classbuffer_size(cb, 4 + 2))
917 /* check attribute length */
919 attribute_length = suck_u4(cb);
921 if (attribute_length != 2) {
922 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
926 if (*signature != NULL) {
927 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
933 signature_index = suck_u2(cb);
935 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
940 #endif /* defined(ENABLE_JAVASE) */
943 /* load_field ******************************************************************
945 Load everything about a class field from the class file and fill a
946 'fieldinfo' structure. For static fields, space in the data segment
949 *******************************************************************************/
951 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
953 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
958 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
963 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
966 f->flags = suck_u2(cb);
968 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
973 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
977 f->parseddesc = NULL;
979 if (!descriptor_pool_add(descpool, u, NULL))
982 /* descriptor_pool_add accepts method descriptors, so we have to check */
983 /* against them here before the call of descriptor_to_basic_type below. */
984 if (u->text[0] == '(') {
985 exceptions_throw_classformaterror(c, "Method descriptor used for field");
989 #ifdef ENABLE_VERIFIER
992 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
993 exceptions_throw_classformaterror(c,
994 "Illegal Field name \"%s\"",
999 /* check flag consistency */
1000 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1002 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1003 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1004 exceptions_throw_classformaterror(c,
1005 "Illegal field modifiers: 0x%X",
1010 if (c->flags & ACC_INTERFACE) {
1011 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1012 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1013 f->flags & ACC_TRANSIENT) {
1014 exceptions_throw_classformaterror(c,
1015 "Illegal field modifiers: 0x%X",
1021 #endif /* ENABLE_VERIFIER */
1023 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1024 f->offset = 0; /* offset from start of object */
1042 if (!(f->flags & ACC_STATIC))
1043 c->flags |= ACC_CLASS_HAS_POINTERS;
1051 f->value.l.high = 0;
1056 /* read attributes */
1057 if (!suck_check_classbuffer_size(cb, 2))
1060 attrnum = suck_u2(cb);
1061 for (i = 0; i < attrnum; i++) {
1062 if (!suck_check_classbuffer_size(cb, 2))
1065 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1068 if (u == utf_ConstantValue) {
1069 if (!suck_check_classbuffer_size(cb, 4 + 2))
1072 /* check attribute length */
1074 if (suck_u4(cb) != 2) {
1075 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1079 /* constant value attribute */
1081 if (pindex != field_load_NOVALUE) {
1082 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1086 /* index of value in constantpool */
1088 pindex = suck_u2(cb);
1090 /* initialize field with value from constantpool */
1093 constant_integer *ci;
1095 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1098 f->value.i = ci->value;
1105 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1108 f->value.l = cl->value;
1115 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1118 f->value.f = cf->value;
1123 constant_double *cd;
1125 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1128 f->value.d = cd->value;
1133 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1136 /* create javastring from compressed utf8-string */
1137 f->value.a = literalstring_new(u);
1141 log_text("Invalid Constant - Type");
1144 #if defined(ENABLE_JAVASE)
1145 else if (u == utf_Signature) {
1148 if (!loader_load_attribute_signature(cb, &(f->signature)))
1153 /* unknown attribute */
1155 if (!loader_skip_attribute_body(cb))
1160 /* everything was ok */
1166 /* loader_load_method **********************************************************
1168 Loads a method from the class file and fills an existing
1169 'methodinfo' structure. For native methods, the function pointer
1170 field is set to the real function pointer, for JavaVM methods a
1171 pointer to the compiler is used preliminarily.
1176 u2 descriptor_index;
1177 u2 attributes_count;
1178 attribute_info attributes[attribute_count];
1182 u2 attribute_name_index;
1183 u4 attribute_length;
1184 u1 info[attribute_length];
1187 LineNumberTable_attribute {
1188 u2 attribute_name_index;
1189 u4 attribute_length;
1190 u2 line_number_table_length;
1194 } line_number_table[line_number_table_length];
1197 *******************************************************************************/
1199 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1200 descriptor_pool *descpool)
1207 u2 descriptor_index;
1208 u2 attributes_count;
1209 u2 attribute_name_index;
1210 utf *attribute_name;
1211 u2 code_attributes_count;
1212 u2 code_attribute_name_index;
1213 utf *code_attribute_name;
1219 #if defined(ENABLE_THREADS)
1220 lock_init_object_lock(&m->header);
1223 #if defined(ENABLE_STATISTICS)
1225 count_all_methods++;
1228 /* all fields of m have been zeroed in load_class_from_classbuffer */
1232 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1237 m->flags = suck_u2(cb);
1241 name_index = suck_u2(cb);
1243 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1250 descriptor_index = suck_u2(cb);
1252 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1257 if (!descriptor_pool_add(descpool, u, &argcount))
1260 #ifdef ENABLE_VERIFIER
1262 if (!is_valid_name_utf(m->name)) {
1263 exceptions_throw_classformaterror(c, "Method with invalid name");
1267 if (m->name->text[0] == '<' &&
1268 m->name != utf_init && m->name != utf_clinit) {
1269 exceptions_throw_classformaterror(c, "Method with invalid special name");
1273 #endif /* ENABLE_VERIFIER */
1275 if (!(m->flags & ACC_STATIC))
1276 argcount++; /* count the 'this' argument */
1278 #ifdef ENABLE_VERIFIER
1280 if (argcount > 255) {
1281 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1285 /* check flag consistency */
1286 if (m->name != utf_clinit) {
1287 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1289 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1290 exceptions_throw_classformaterror(c,
1291 "Illegal method modifiers: 0x%X",
1296 if (m->flags & ACC_ABSTRACT) {
1297 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1298 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1299 exceptions_throw_classformaterror(c,
1300 "Illegal method modifiers: 0x%X",
1306 if (c->flags & ACC_INTERFACE) {
1307 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1308 exceptions_throw_classformaterror(c,
1309 "Illegal method modifiers: 0x%X",
1315 if (m->name == utf_init) {
1316 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1317 ACC_NATIVE | ACC_ABSTRACT)) {
1318 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1324 #endif /* ENABLE_VERIFIER */
1326 /* mark the method as monomorphic until further notice */
1328 m->flags |= ACC_METHOD_MONOMORPHIC;
1330 /* non-abstract methods have an implementation in this class */
1332 if (!(m->flags & ACC_ABSTRACT))
1333 m->flags |= ACC_METHOD_IMPLEMENTED;
1335 if (!suck_check_classbuffer_size(cb, 2))
1338 /* attributes count */
1340 attributes_count = suck_u2(cb);
1342 for (i = 0; i < attributes_count; i++) {
1343 if (!suck_check_classbuffer_size(cb, 2))
1346 /* attribute name index */
1348 attribute_name_index = suck_u2(cb);
1350 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1353 if (attribute_name == utf_Code) {
1355 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1356 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1361 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1365 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1369 m->maxstack = suck_u2(cb);
1370 m->maxlocals = suck_u2(cb);
1372 if (m->maxlocals < argcount) {
1373 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1377 if (!suck_check_classbuffer_size(cb, 4))
1380 m->jcodelength = suck_u4(cb);
1382 if (m->jcodelength == 0) {
1383 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1387 if (m->jcodelength > 65535) {
1388 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1392 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1395 m->jcode = MNEW(u1, m->jcodelength);
1396 suck_nbytes(m->jcode, cb, m->jcodelength);
1398 if (!suck_check_classbuffer_size(cb, 2))
1401 m->rawexceptiontablelength = suck_u2(cb);
1402 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1405 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1407 #if defined(ENABLE_STATISTICS)
1409 count_vmcode_len += m->jcodelength + 18;
1410 count_extable_len +=
1411 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1415 for (j = 0; j < m->rawexceptiontablelength; j++) {
1417 m->rawexceptiontable[j].startpc = suck_u2(cb);
1418 m->rawexceptiontable[j].endpc = suck_u2(cb);
1419 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1423 m->rawexceptiontable[j].catchtype.any = NULL;
1426 /* the classref is created later */
1427 if (!(m->rawexceptiontable[j].catchtype.any =
1428 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1433 if (!suck_check_classbuffer_size(cb, 2))
1436 /* code attributes count */
1438 code_attributes_count = suck_u2(cb);
1440 for (k = 0; k < code_attributes_count; k++) {
1441 if (!suck_check_classbuffer_size(cb, 2))
1444 /* code attribute name index */
1446 code_attribute_name_index = suck_u2(cb);
1448 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1451 /* check which code attribute */
1453 if (code_attribute_name == utf_LineNumberTable) {
1454 /* LineNumberTable */
1455 if (!suck_check_classbuffer_size(cb, 4 + 2))
1458 /* attribute length */
1462 /* line number table length */
1464 m->linenumbercount = suck_u2(cb);
1466 if (!suck_check_classbuffer_size(cb,
1467 (2 + 2) * m->linenumbercount))
1470 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1472 #if defined(ENABLE_STATISTICS)
1474 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1477 for (l = 0; l < m->linenumbercount; l++) {
1478 m->linenumbers[l].start_pc = suck_u2(cb);
1479 m->linenumbers[l].line_number = suck_u2(cb);
1482 #if defined(ENABLE_JAVASE)
1483 else if (code_attribute_name == utf_StackMapTable) {
1486 if (!stackmap_load_attribute_stackmaptable(cb, m))
1491 /* unknown code attribute */
1493 if (!loader_skip_attribute_body(cb))
1498 else if (attribute_name == utf_Exceptions) {
1501 if (m->thrownexceptions != NULL) {
1502 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1506 if (!suck_check_classbuffer_size(cb, 4 + 2))
1509 /* attribute length */
1513 m->thrownexceptionscount = suck_u2(cb);
1515 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1518 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1520 for (j = 0; j < m->thrownexceptionscount; j++) {
1521 /* the classref is created later */
1522 if (!((m->thrownexceptions)[j].any =
1523 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1527 #if defined(ENABLE_JAVASE)
1528 else if (attribute_name == utf_Signature) {
1531 if (!loader_load_attribute_signature(cb, &(m->signature)))
1536 /* unknown attribute */
1538 if (!loader_skip_attribute_body(cb))
1543 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1544 exceptions_throw_classformaterror(c, "Missing Code attribute");
1548 /* initialize the hit countdown field */
1550 #if defined(ENABLE_REPLACEMENT)
1551 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1554 /* everything was ok */
1560 /* load_class_from_sysloader ***************************************************
1562 Load the class with the given name using the system class loader
1565 name.............the classname
1568 the loaded class, or
1569 NULL if an exception has been thrown
1571 *******************************************************************************/
1573 classinfo *load_class_from_sysloader(utf *name)
1576 java_objectheader *clo;
1580 assert(class_java_lang_Object);
1581 assert(class_java_lang_ClassLoader);
1582 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1584 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1585 utf_getSystemClassLoader,
1586 utf_void__java_lang_ClassLoader,
1587 class_java_lang_Object,
1593 clo = vm_call_method(m, NULL);
1598 cl = loader_hashtable_classloader_add(clo);
1600 c = load_class_from_classloader(name, cl);
1606 /* load_class_from_classloader *************************************************
1608 Load the class with the given name using the given user-defined class loader.
1611 name.............the classname
1612 cl...............user-defined class loader
1615 the loaded class, or
1616 NULL if an exception has been thrown
1618 *******************************************************************************/
1620 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1622 java_objectheader *o;
1625 java_objectheader *string;
1626 #if defined(ENABLE_RT_TIMING)
1627 struct timespec time_start, time_lookup, time_prepare, time_java,
1631 RT_TIMING_GET_TIME(time_start);
1635 /* lookup if this class has already been loaded */
1637 c = classcache_lookup(cl, name);
1639 RT_TIMING_GET_TIME(time_lookup);
1640 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1645 /* if other class loader than bootstrap, call it */
1653 namelen = name->blength;
1655 /* handle array classes */
1656 if (text[0] == '[') {
1662 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1663 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1664 exceptions_throw_noclassdeffounderror(name);
1668 u = utf_new(text + 2, namelen - 3);
1670 if (!(comp = load_class_from_classloader(u, cl)))
1673 /* create the array class */
1675 c = class_array_of(comp, false);
1677 tmpc = classcache_store(cl, c, true);
1680 /* exception, free the loaded class */
1681 c->state &= ~CLASS_LOADING;
1688 /* load the component class */
1690 u = utf_new(text + 1, namelen - 1);
1692 if (!(comp = load_class_from_classloader(u, cl)))
1695 /* create the array class */
1697 c = class_array_of(comp, false);
1699 tmpc = classcache_store(cl, c, true);
1702 /* exception, free the loaded class */
1703 c->state &= ~CLASS_LOADING;
1710 /* primitive array classes are loaded by the bootstrap loader */
1712 c = load_class_bootstrap(name);
1718 assert(class_java_lang_Object);
1720 lc = class_resolveclassmethod(cl->object->vftbl->class,
1722 utf_java_lang_String__java_lang_Class,
1723 class_java_lang_Object,
1727 return false; /* exception */
1729 /* move return value into `o' and cast it afterwards to a classinfo* */
1731 string = javastring_new_slash_to_dot(name);
1733 RT_TIMING_GET_TIME(time_prepare);
1735 o = vm_call_method(lc, cl->object, string);
1737 RT_TIMING_GET_TIME(time_java);
1739 c = (classinfo *) o;
1742 /* Store this class in the loaded class cache. If another
1743 class with the same (initloader,name) pair has been
1744 stored earlier it will be returned by classcache_store
1745 In this case classcache_store may not free the class
1746 because it has already been exposed to Java code which
1747 may have kept references to that class. */
1749 tmpc = classcache_store(cl, c, false);
1752 /* exception, free the loaded class */
1753 c->state &= ~CLASS_LOADING;
1760 /* loadClass has thrown an exception. We must convert
1761 ClassNotFoundException into
1762 NoClassDefFoundException. */
1764 /* XXX Maybe we should have a flag that avoids this
1765 conversion for calling load_class_from_classloader from
1766 Class.forName. Currently we do a double conversion in
1769 classnotfoundexception_to_noclassdeffounderror();
1772 RT_TIMING_GET_TIME(time_cache);
1774 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1775 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1776 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1778 /* SUN compatible -verbose:class output */
1780 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1782 utf_display_printable_ascii_classname(name);
1786 #if defined(ENABLE_JVMTI)
1787 /* fire Class Load JVMTI event */
1788 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1795 c = load_class_bootstrap(name);
1801 /* load_class_bootstrap ********************************************************
1803 Load the class with the given name using the bootstrap class loader.
1806 name.............the classname
1809 loaded classinfo, or
1810 NULL if an exception has been thrown
1813 load_class_bootstrap is synchronized. It can be treated as an
1816 *******************************************************************************/
1818 classinfo *load_class_bootstrap(utf *name)
1823 #if defined(ENABLE_RT_TIMING)
1824 struct timespec time_start, time_lookup, time_array, time_suck,
1825 time_load, time_cache;
1828 RT_TIMING_GET_TIME(time_start);
1834 /* lookup if this class has already been loaded */
1836 if ((r = classcache_lookup(NULL, name))) {
1838 RT_TIMING_GET_TIME(time_lookup);
1839 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1844 RT_TIMING_GET_TIME(time_lookup);
1845 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1847 /* create the classinfo */
1849 c = class_create_classinfo(name);
1851 /* handle array classes */
1853 if (name->text[0] == '[') {
1854 c = load_newly_created_array(c, NULL);
1857 assert(c->state & CLASS_LOADED);
1859 RT_TIMING_GET_TIME(time_array);
1860 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1865 #if defined(ENABLE_STATISTICS)
1868 if (opt_getcompilingtime)
1869 compilingtime_stop();
1871 if (opt_getloadingtime)
1872 loadingtime_start();
1875 /* load classdata, throw exception on error */
1880 /* this normally means, the classpath was not set properly */
1882 if (name == utf_java_lang_Object)
1883 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1885 exceptions_throw_noclassdeffounderror(name);
1890 RT_TIMING_GET_TIME(time_suck);
1892 /* load the class from the buffer */
1894 r = load_class_from_classbuffer(cb);
1896 RT_TIMING_GET_TIME(time_load);
1899 /* the class could not be loaded, free the classinfo struct */
1904 /* Store this class in the loaded class cache this step also
1905 checks the loading constraints. If the class has been loaded
1906 before, the earlier loaded class is returned. */
1908 classinfo *res = classcache_store(NULL, c, true);
1918 RT_TIMING_GET_TIME(time_cache);
1920 /* SUN compatible -verbose:class output */
1922 if (opt_verboseclass && r) {
1924 utf_display_printable_ascii_classname(name);
1925 printf(" from %s]\n", cb->path);
1932 #if defined(ENABLE_STATISTICS)
1935 if (opt_getloadingtime)
1938 if (opt_getcompilingtime)
1939 compilingtime_start();
1942 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1943 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1944 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1945 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1951 /* load_class_from_classbuffer *************************************************
1953 Loads everything interesting about a class from the class file. The
1954 'classinfo' structure must have been allocated previously.
1956 The super class and the interfaces implemented by this class need
1957 not be loaded. The link is set later by the function 'class_link'.
1959 The loaded class is removed from the list 'unloadedclasses' and
1960 added to the list 'unlinkedclasses'.
1963 This function is NOT synchronized!
1965 *******************************************************************************/
1967 classinfo *load_class_from_classbuffer(classbuffer *cb)
1975 descriptor_pool *descpool;
1976 #if defined(ENABLE_STATISTICS)
1980 #if defined(ENABLE_RT_TIMING)
1981 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1982 time_setup, time_fields, time_methods, time_classrefs,
1983 time_descs, time_setrefs, time_parsefds, time_parsemds,
1984 time_parsecpool, time_verify, time_attrs;
1987 RT_TIMING_GET_TIME(time_start);
1989 /* get the classbuffer's class */
1993 /* the class is already loaded */
1995 if (c->state & CLASS_LOADED)
1998 #if defined(ENABLE_STATISTICS)
2000 count_class_loads++;
2003 #if !defined(NDEBUG)
2004 /* output for debugging purposes */
2007 log_message_class("Loading class: ", c);
2010 /* mark start of dump memory area */
2012 dumpsize = dump_size();
2014 /* class is currently loading */
2016 c->state |= CLASS_LOADING;
2018 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2019 goto return_exception;
2021 /* check signature */
2023 if (suck_u4(cb) != MAGIC) {
2024 exceptions_throw_classformaterror(c, "Bad magic number");
2026 goto return_exception;
2034 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2035 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2036 goto return_exception;
2039 RT_TIMING_GET_TIME(time_checks);
2041 /* create a new descriptor pool */
2043 descpool = descriptor_pool_new(c);
2045 RT_TIMING_GET_TIME(time_ndpool);
2047 /* load the constant pool */
2049 if (!load_constantpool(cb, descpool))
2050 goto return_exception;
2052 RT_TIMING_GET_TIME(time_cpool);
2056 if (!suck_check_classbuffer_size(cb, 2))
2057 goto return_exception;
2059 /* We OR the flags here, as we set already some flags in
2060 class_create_classinfo. */
2062 c->flags |= suck_u2(cb);
2064 /* check ACC flags consistency */
2066 if (c->flags & ACC_INTERFACE) {
2067 if (!(c->flags & ACC_ABSTRACT)) {
2068 /* We work around this because interfaces in JDK 1.1 are
2069 * not declared abstract. */
2071 c->flags |= ACC_ABSTRACT;
2074 if (c->flags & ACC_FINAL) {
2075 exceptions_throw_classformaterror(c,
2076 "Illegal class modifiers: 0x%X",
2078 goto return_exception;
2081 if (c->flags & ACC_SUPER) {
2082 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2086 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2087 exceptions_throw_classformaterror(c,
2088 "Illegal class modifiers: 0x%X",
2090 goto return_exception;
2093 if (!suck_check_classbuffer_size(cb, 2 + 2))
2094 goto return_exception;
2100 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2101 goto return_exception;
2103 if (c->name == utf_not_named_yet) {
2104 /* we finally have a name for this class */
2106 class_set_packagename(c);
2108 else if (name != c->name) {
2109 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
2110 goto return_exception;
2113 /* retrieve superclass */
2115 c->super.any = NULL;
2117 if ((i = suck_u2(cb))) {
2118 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2119 goto return_exception;
2121 /* java.lang.Object may not have a super class. */
2123 if (c->name == utf_java_lang_Object) {
2124 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2125 goto return_exception;
2128 /* Interfaces must have java.lang.Object as super class. */
2130 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2131 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2132 goto return_exception;
2138 /* This is only allowed for java.lang.Object. */
2140 if (c->name != utf_java_lang_Object) {
2141 exceptions_throw_classformaterror(c, "Bad superclass index");
2142 goto return_exception;
2146 /* retrieve interfaces */
2148 if (!suck_check_classbuffer_size(cb, 2))
2149 goto return_exception;
2151 c->interfacescount = suck_u2(cb);
2153 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2154 goto return_exception;
2156 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2157 for (i = 0; i < c->interfacescount; i++) {
2158 /* the classrefs are created later */
2159 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2160 goto return_exception;
2163 RT_TIMING_GET_TIME(time_setup);
2166 if (!suck_check_classbuffer_size(cb, 2))
2167 goto return_exception;
2169 c->fieldscount = suck_u2(cb);
2170 #if defined(ENABLE_GC_CACAO)
2171 c->fields = MNEW(fieldinfo, c->fieldscount);
2172 MZERO(c->fields, fieldinfo, c->fieldscount);
2174 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2177 for (i = 0; i < c->fieldscount; i++) {
2178 if (!load_field(cb, &(c->fields[i]),descpool))
2179 goto return_exception;
2182 RT_TIMING_GET_TIME(time_fields);
2185 if (!suck_check_classbuffer_size(cb, 2))
2186 goto return_exception;
2188 c->methodscount = suck_u2(cb);
2189 c->methods = MNEW(methodinfo, c->methodscount);
2191 MZERO(c->methods, methodinfo, c->methodscount);
2193 for (i = 0; i < c->methodscount; i++) {
2194 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2195 goto return_exception;
2198 RT_TIMING_GET_TIME(time_methods);
2200 /* create the class reference table */
2203 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2205 RT_TIMING_GET_TIME(time_classrefs);
2207 /* allocate space for the parsed descriptors */
2209 descriptor_pool_alloc_parsed_descriptors(descpool);
2211 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2213 #if defined(ENABLE_STATISTICS)
2215 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2216 count_classref_len += classrefsize;
2217 count_parsed_desc_len += descsize;
2221 RT_TIMING_GET_TIME(time_descs);
2223 /* put the classrefs in the constant pool */
2224 for (i = 0; i < c->cpcount; i++) {
2225 if (c->cptags[i] == CONSTANT_Class) {
2226 utf *name = (utf *) c->cpinfos[i];
2227 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2231 /* set the super class reference */
2234 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2236 goto return_exception;
2239 /* set the super interfaces references */
2241 for (i = 0; i < c->interfacescount; i++) {
2242 c->interfaces[i].ref =
2243 descriptor_pool_lookup_classref(descpool,
2244 (utf *) c->interfaces[i].any);
2245 if (!c->interfaces[i].ref)
2246 goto return_exception;
2249 RT_TIMING_GET_TIME(time_setrefs);
2251 /* parse field descriptors */
2253 for (i = 0; i < c->fieldscount; i++) {
2254 c->fields[i].parseddesc =
2255 descriptor_pool_parse_field_descriptor(descpool,
2256 c->fields[i].descriptor);
2257 if (!c->fields[i].parseddesc)
2258 goto return_exception;
2261 RT_TIMING_GET_TIME(time_parsefds);
2263 /* parse method descriptors */
2265 for (i = 0; i < c->methodscount; i++) {
2266 methodinfo *m = &c->methods[i];
2268 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2269 m->flags, class_get_self_classref(m->class));
2271 goto return_exception;
2273 for (j = 0; j < m->rawexceptiontablelength; j++) {
2274 if (!m->rawexceptiontable[j].catchtype.any)
2276 if ((m->rawexceptiontable[j].catchtype.ref =
2277 descriptor_pool_lookup_classref(descpool,
2278 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2279 goto return_exception;
2282 for (j = 0; j < m->thrownexceptionscount; j++) {
2283 if (!m->thrownexceptions[j].any)
2285 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2286 (utf *) m->thrownexceptions[j].any)) == NULL)
2287 goto return_exception;
2291 RT_TIMING_GET_TIME(time_parsemds);
2293 /* parse the loaded descriptors */
2295 for (i = 0; i < c->cpcount; i++) {
2296 constant_FMIref *fmi;
2299 switch (c->cptags[i]) {
2300 case CONSTANT_Fieldref:
2301 fmi = (constant_FMIref *) c->cpinfos[i];
2302 fmi->parseddesc.fd =
2303 descriptor_pool_parse_field_descriptor(descpool,
2305 if (!fmi->parseddesc.fd)
2306 goto return_exception;
2307 index = fmi->p.index;
2309 (constant_classref *) class_getconstant(c, index,
2311 if (!fmi->p.classref)
2312 goto return_exception;
2314 case CONSTANT_Methodref:
2315 case CONSTANT_InterfaceMethodref:
2316 fmi = (constant_FMIref *) c->cpinfos[i];
2317 index = fmi->p.index;
2319 (constant_classref *) class_getconstant(c, index,
2321 if (!fmi->p.classref)
2322 goto return_exception;
2323 fmi->parseddesc.md =
2324 descriptor_pool_parse_method_descriptor(descpool,
2328 if (!fmi->parseddesc.md)
2329 goto return_exception;
2334 RT_TIMING_GET_TIME(time_parsecpool);
2336 #ifdef ENABLE_VERIFIER
2337 /* Check if all fields and methods can be uniquely
2338 * identified by (name,descriptor). */
2341 /* We use a hash table here to avoid making the
2342 * average case quadratic in # of methods, fields.
2344 static int shift = 0;
2346 u2 *next; /* for chaining colliding hash entries */
2352 /* Allocate hashtable */
2353 len = c->methodscount;
2354 if (len < c->fieldscount) len = c->fieldscount;
2356 hashtab = MNEW(u2,(hashlen + len));
2357 next = hashtab + hashlen;
2359 /* Determine bitshift (to get good hash values) */
2369 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2371 for (i = 0; i < c->fieldscount; ++i) {
2372 fieldinfo *fi = c->fields + i;
2374 /* It's ok if we lose bits here */
2375 index = ((((size_t) fi->name) +
2376 ((size_t) fi->descriptor)) >> shift) % hashlen;
2378 if ((old = hashtab[index])) {
2382 if (c->fields[old].name == fi->name &&
2383 c->fields[old].descriptor == fi->descriptor) {
2384 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2385 goto return_exception;
2387 } while ((old = next[old]));
2389 hashtab[index] = i + 1;
2393 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2395 for (i = 0; i < c->methodscount; ++i) {
2396 methodinfo *mi = c->methods + i;
2398 /* It's ok if we lose bits here */
2399 index = ((((size_t) mi->name) +
2400 ((size_t) mi->descriptor)) >> shift) % hashlen;
2404 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2405 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2409 if ((old = hashtab[index])) {
2413 if (c->methods[old].name == mi->name &&
2414 c->methods[old].descriptor == mi->descriptor) {
2415 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2416 goto return_exception;
2418 } while ((old = next[old]));
2420 hashtab[index] = i + 1;
2423 MFREE(hashtab, u2, (hashlen + len));
2425 #endif /* ENABLE_VERIFIER */
2427 RT_TIMING_GET_TIME(time_verify);
2429 #if defined(ENABLE_STATISTICS)
2431 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2432 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2433 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2437 /* load attribute structures */
2439 if (!class_load_attributes(cb))
2440 goto return_exception;
2442 /* Pre Java 1.5 version don't check this. This implementation is like
2443 Java 1.5 do it: for class file version 45.3 we don't check it, older
2444 versions are checked.
2447 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2448 /* check if all data has been read */
2449 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2451 if (classdata_left > 0) {
2452 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2453 goto return_exception;
2457 RT_TIMING_GET_TIME(time_attrs);
2459 /* release dump area */
2461 dump_release(dumpsize);
2463 /* revert loading state and class is loaded */
2465 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2467 #if defined(ENABLE_JVMTI)
2468 /* fire Class Prepare JVMTI event */
2471 jvmti_ClassLoadPrepare(true, c);
2474 #if !defined(NDEBUG)
2476 log_message_class("Loading done class: ", c);
2479 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2480 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2481 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2482 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2483 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2484 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2485 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2486 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2487 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2488 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2489 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2490 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2491 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2492 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2493 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2498 /* release dump area */
2500 dump_release(dumpsize);
2502 /* an exception has been thrown */
2508 /* load_newly_created_array ****************************************************
2510 Load a newly created array class.
2513 c....................the array class C has been loaded
2514 other classinfo......the array class was found in the class cache,
2516 NULL.................an exception has been thrown
2519 This is an internal function. Do not use it unless you know exactly
2522 Use one of the load_class_... functions for general array class loading.
2524 *******************************************************************************/
2526 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2528 classinfo *comp = NULL;
2530 methoddesc *clonedesc;
2531 constant_classref *classrefs;
2536 text = c->name->text;
2537 namelen = c->name->blength;
2539 /* Check array class name */
2541 if ((namelen < 2) || (text[0] != '[')) {
2542 exceptions_throw_noclassdeffounderror(c->name);
2546 /* Check the element type */
2550 /* c is an array of arrays. We have to create the component class. */
2552 u = utf_new(text + 1, namelen - 1);
2553 if (!(comp = load_class_from_classloader(u, loader)))
2556 assert(comp->state & CLASS_LOADED);
2562 /* the array's flags are that of the component class */
2563 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2564 c->classloader = comp->classloader;
2568 /* c is an array of objects. */
2570 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2571 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2572 exceptions_throw_noclassdeffounderror(c->name);
2576 u = utf_new(text + 2, namelen - 3);
2578 if (!(comp = load_class_from_classloader(u, loader)))
2581 assert(comp->state & CLASS_LOADED);
2587 /* the array's flags are that of the component class */
2588 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2589 c->classloader = comp->classloader;
2593 /* c is an array of a primitive type */
2595 /* check for cases like `[II' */
2597 exceptions_throw_noclassdeffounderror(c->name);
2601 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2602 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2603 c->classloader = NULL;
2606 assert(class_java_lang_Object);
2607 #if defined(ENABLE_JAVASE)
2608 assert(class_java_lang_Cloneable);
2609 assert(class_java_io_Serializable);
2612 /* setup the array class */
2614 c->super.cls = class_java_lang_Object;
2616 #if defined(ENABLE_JAVASE)
2617 c->interfacescount = 2;
2618 c->interfaces = MNEW(classref_or_classinfo, 2);
2623 tc = class_java_lang_Cloneable;
2624 assert(tc->state & CLASS_LOADED);
2625 list_add_first(&unlinkedclasses, tc);
2626 c->interfaces[0].cls = tc;
2628 tc = class_java_io_Serializable;
2629 assert(tc->state & CLASS_LOADED);
2630 list_add_first(&unlinkedclasses, tc);
2631 c->interfaces[1].cls = tc;
2634 c->interfaces[0].cls = class_java_lang_Cloneable;
2635 c->interfaces[1].cls = class_java_io_Serializable;
2637 #elif defined(ENABLE_JAVAME_CLDC1_1)
2638 c->interfacescount = 0;
2639 c->interfaces = NULL;
2641 #error unknow Java configuration
2644 c->methodscount = 1;
2645 c->methods = MNEW(methodinfo, c->methodscount);
2646 MZERO(c->methods, methodinfo, c->methodscount);
2648 classrefs = MNEW(constant_classref, 2);
2649 CLASSREF_INIT(classrefs[0], c, c->name);
2650 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2652 /* create descriptor for clone method */
2653 /* we need one paramslot which is reserved for the 'this' parameter */
2654 clonedesc = NEW(methoddesc);
2655 clonedesc->returntype.type = TYPE_ADR;
2656 clonedesc->returntype.classref = classrefs + 1;
2657 clonedesc->returntype.arraydim = 0;
2658 /* initialize params to "empty", add real params below in
2659 descriptor_params_from_paramtypes */
2660 clonedesc->paramcount = 0;
2661 clonedesc->paramslots = 0;
2662 clonedesc->paramtypes[0].classref = classrefs + 0;
2663 clonedesc->params = NULL;
2665 /* create methodinfo */
2668 MSET(clone, 0, methodinfo, 1);
2670 #if defined(ENABLE_THREADS)
2671 lock_init_object_lock(&clone->header);
2674 /* ATTENTION: if you delete the ACC_NATIVE below, set
2675 clone->maxlocals=1 (interpreter related) */
2677 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2678 clone->name = utf_clone;
2679 clone->descriptor = utf_void__java_lang_Object;
2680 clone->parseddesc = clonedesc;
2683 /* parse the descriptor to get the register allocation */
2685 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2688 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2690 /* XXX: field: length? */
2692 /* array classes are not loaded from class files */
2694 c->state |= CLASS_LOADED;
2695 c->parseddescs = (u1 *) clonedesc;
2696 c->parseddescsize = sizeof(methodinfo);
2697 c->classrefs = classrefs;
2698 c->classrefcount = 1;
2700 /* insert class into the loaded class cache */
2701 /* XXX free classinfo if NULL returned? */
2703 return classcache_store(loader, c, true);
2707 /* loader_close ****************************************************************
2709 Frees all resources.
2711 *******************************************************************************/
2713 void loader_close(void)
2720 * These are local overrides for various environment variables in Emacs.
2721 * Please do not remove this and leave it at the end of the file, where
2722 * Emacs will automagically detect them.
2723 * ---------------------------------------------------------------------
2726 * indent-tabs-mode: t
2730 * vim:noexpandtab:sw=4:ts=4: