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 7693 2007-04-12 14:56:49Z michi $
38 #include "mm/memory.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
43 # include "threads/none/lock.h"
46 #include "toolbox/hashtable.h"
47 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit_interface.h"
57 #if defined(ENABLE_JAVASE)
58 # include "vmcore/annotation.h"
59 # include "vmcore/stackmap.h"
62 #include "vmcore/classcache.h"
63 #include "vmcore/linker.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
66 #include "vmcore/rt-timing.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vmcore/statistics.h"
72 #include "vmcore/suck.h"
74 #if defined(ENABLE_ZLIB)
75 # include "vmcore/zip.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 hashtable *hashtable_classloader;
88 /* loader_init *****************************************************************
90 Initializes all lists and loads all classes required for the system
93 *******************************************************************************/
95 bool loader_init(void)
97 #if defined(ENABLE_THREADS)
98 list_classpath_entry *lce;
100 /* Initialize the monitor pointer for zip/jar file locking. */
102 for (lce = list_first(list_classpath_entries); lce != NULL;
103 lce = list_next(list_classpath_entries, lce))
104 if (lce->type == CLASSPATH_ARCHIVE)
105 lock_init_object_lock((java_objectheader *) lce);
108 /* initialize classloader hashtable, 10 entries should be enough */
110 hashtable_classloader = NEW(hashtable);
111 hashtable_create(hashtable_classloader, 10);
113 /* load some important classes */
115 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
118 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
121 #if defined(ENABLE_JAVASE)
122 if (!(class_java_lang_Cloneable =
123 load_class_bootstrap(utf_java_lang_Cloneable)))
126 if (!(class_java_io_Serializable =
127 load_class_bootstrap(utf_java_io_Serializable)))
131 /* load classes for wrapping primitive types */
133 #if defined(ENABLE_JAVASE)
134 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
138 if (!(class_java_lang_Boolean =
139 load_class_bootstrap(utf_java_lang_Boolean)))
142 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
145 if (!(class_java_lang_Character =
146 load_class_bootstrap(utf_java_lang_Character)))
149 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
152 if (!(class_java_lang_Integer =
153 load_class_bootstrap(utf_java_lang_Integer)))
156 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
159 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
162 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
166 /* load some other important classes */
168 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
171 #if defined(ENABLE_JAVASE)
172 if (!(class_java_lang_ClassLoader =
173 load_class_bootstrap(utf_java_lang_ClassLoader)))
176 if (!(class_java_lang_SecurityManager =
177 load_class_bootstrap(utf_java_lang_SecurityManager)))
181 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
184 if (!(class_java_lang_Thread =
185 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
188 #if defined(ENABLE_JAVASE)
189 if (!(class_java_lang_ThreadGroup =
190 load_class_bootstrap(utf_java_lang_ThreadGroup)))
194 #if defined(WITH_CLASSPATH_GNU)
195 if (!(class_java_lang_VMSystem =
196 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
200 if (!(class_java_lang_VMThread =
201 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
206 /* some classes which may be used more often */
208 #if defined(ENABLE_JAVASE)
209 if (!(class_java_lang_StackTraceElement =
210 load_class_bootstrap(utf_java_lang_StackTraceElement)))
213 if (!(class_java_lang_reflect_Constructor =
214 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
217 if (!(class_java_lang_reflect_Field =
218 load_class_bootstrap(utf_java_lang_reflect_Field)))
221 if (!(class_java_lang_reflect_Method =
222 load_class_bootstrap(utf_java_lang_reflect_Method)))
225 if (!(class_java_security_PrivilegedAction =
226 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
229 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
232 if (!(arrayclass_java_lang_Object =
233 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
241 /* loader_hashtable_classloader_add ********************************************
243 Adds an entry to the classloader hashtable.
245 REMEMBER: Also use this to register native loaders!
247 *******************************************************************************/
249 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
251 hashtable_classloader_entry *cle;
258 LOCK_MONITOR_ENTER(hashtable_classloader->header);
260 /* key for entry is the hashcode of the classloader;
261 aligned to 16-byte boundaries */
263 #if defined(ENABLE_GC_CACAO)
264 key = heap_get_hashcode(cl) >> 4;
266 key = ((u4) (ptrint) cl) >> 4;
269 slot = key & (hashtable_classloader->size - 1);
270 cle = hashtable_classloader->ptr[slot];
272 /* search hashchain for existing entry */
273 /* XXX no GC collection is allowed here, make this a critical section */
276 if (cle->object == cl)
282 /* if no classloader was found, we create a new entry here */
285 cle = NEW(hashtable_classloader_entry);
289 /* insert entry into hashtable */
291 cle->hashlink = hashtable_classloader->ptr[slot];
292 hashtable_classloader->ptr[slot] = cle;
294 /* update number of entries */
296 hashtable_classloader->entries++;
300 LOCK_MONITOR_EXIT(hashtable_classloader->header);
306 /* loader_hashtable_classloader_find *******************************************
308 Find an entry in the classloader hashtable.
310 *******************************************************************************/
312 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
314 hashtable_classloader_entry *cle;
321 /* key for entry is the hashcode of the classloader;
322 aligned to 16-byte boundaries */
324 #if defined(ENABLE_GC_CACAO)
325 key = heap_get_hashcode(cl) >> 4;
327 key = ((u4) (ptrint) cl) >> 4;
330 slot = key & (hashtable_classloader->size - 1);
331 cle = hashtable_classloader->ptr[slot];
333 /* search hashchain for existing entry */
334 /* XXX no GC collection is allowed here, make this a critical section */
337 if (cle->object == cl)
347 /* loader_load_all_classes *****************************************************
349 Loads all classes specified in the BOOTCLASSPATH.
351 *******************************************************************************/
353 void loader_load_all_classes(void)
355 list_classpath_entry *lce;
356 #if defined(ENABLE_ZLIB)
359 hashtable_zipfile_entry *htzfe;
363 for (lce = list_first(list_classpath_entries); lce != NULL;
364 lce = list_next(list_classpath_entries, lce)) {
365 #if defined(ENABLE_ZLIB)
366 if (lce->type == CLASSPATH_ARCHIVE) {
367 /* get the classes hashtable */
371 for (slot = 0; slot < ht->size; slot++) {
372 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
374 for (; htzfe; htzfe = htzfe->hashlink) {
377 /* skip all entries in META-INF and .properties,
380 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
381 strstr(u->text, ".properties") ||
382 strstr(u->text, ".png"))
385 /* load class from bootstrap classloader */
387 if (!load_class_bootstrap(u)) {
388 fprintf(stderr, "Error loading: ");
389 utf_fprint_printable_ascii_classname(stderr, u);
390 fprintf(stderr, "\n");
393 /* print out exception and cause */
395 exceptions_print_current_exception();
403 #if defined(ENABLE_ZLIB)
410 /* loader_skip_attribute_body **************************************************
412 Skips an attribute the attribute_name_index has already been read.
415 u2 attribute_name_index;
417 u1 info[attribute_length];
420 *******************************************************************************/
422 bool loader_skip_attribute_body(classbuffer *cb)
426 if (!suck_check_classbuffer_size(cb, 4))
429 attribute_length = suck_u4(cb);
431 if (!suck_check_classbuffer_size(cb, attribute_length))
434 suck_skip_nbytes(cb, attribute_length);
440 /* load_constantpool ***********************************************************
442 Loads the constantpool of a class, the entries are transformed into
443 a simpler format by resolving references (a detailed overview of
444 the compact structures can be found in global.h).
446 *******************************************************************************/
448 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
451 /* The following structures are used to save information which cannot be
452 processed during the first pass. After the complete constantpool has
453 been traversed the references can be resolved.
454 (only in specific order) */
456 /* CONSTANT_Class entries */
457 typedef struct forward_class {
458 struct forward_class *next;
463 /* CONSTANT_String */
464 typedef struct forward_string {
465 struct forward_string *next;
470 /* CONSTANT_NameAndType */
471 typedef struct forward_nameandtype {
472 struct forward_nameandtype *next;
476 } forward_nameandtype;
478 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
479 typedef struct forward_fieldmethint {
480 struct forward_fieldmethint *next;
484 u2 nameandtype_index;
485 } forward_fieldmethint;
491 forward_class *forward_classes = NULL;
492 forward_string *forward_strings = NULL;
493 forward_nameandtype *forward_nameandtypes = NULL;
494 forward_fieldmethint *forward_fieldmethints = NULL;
498 forward_nameandtype *nfn;
499 forward_fieldmethint *nff;
507 /* number of entries in the constant_pool table plus one */
508 if (!suck_check_classbuffer_size(cb, 2))
511 cpcount = c->cpcount = suck_u2(cb);
513 /* allocate memory */
514 cptags = c->cptags = MNEW(u1, cpcount);
515 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
518 exceptions_throw_classformaterror(c, "Illegal constant pool size");
522 #if defined(ENABLE_STATISTICS)
524 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
527 /* initialize constantpool */
528 for (idx = 0; idx < cpcount; idx++) {
529 cptags[idx] = CONSTANT_UNUSED;
534 /******* first pass *******/
535 /* entries which cannot be resolved now are written into
536 temporary structures and traversed again later */
539 while (idx < cpcount) {
542 /* get constant type */
543 if (!suck_check_classbuffer_size(cb, 1))
550 nfc = DNEW(forward_class);
552 nfc->next = forward_classes;
553 forward_classes = nfc;
555 nfc->thisindex = idx;
556 /* reference to CONSTANT_NameAndType */
557 if (!suck_check_classbuffer_size(cb, 2))
560 nfc->name_index = suck_u2(cb);
565 case CONSTANT_String:
566 nfs = DNEW(forward_string);
568 nfs->next = forward_strings;
569 forward_strings = nfs;
571 nfs->thisindex = idx;
573 /* reference to CONSTANT_Utf8_info with string characters */
574 if (!suck_check_classbuffer_size(cb, 2))
577 nfs->string_index = suck_u2(cb);
582 case CONSTANT_NameAndType:
583 nfn = DNEW(forward_nameandtype);
585 nfn->next = forward_nameandtypes;
586 forward_nameandtypes = nfn;
588 nfn->thisindex = idx;
590 if (!suck_check_classbuffer_size(cb, 2 + 2))
593 /* reference to CONSTANT_Utf8_info containing simple name */
594 nfn->name_index = suck_u2(cb);
596 /* reference to CONSTANT_Utf8_info containing field or method
598 nfn->sig_index = suck_u2(cb);
603 case CONSTANT_Fieldref:
604 case CONSTANT_Methodref:
605 case CONSTANT_InterfaceMethodref:
606 nff = DNEW(forward_fieldmethint);
608 nff->next = forward_fieldmethints;
609 forward_fieldmethints = nff;
611 nff->thisindex = idx;
615 if (!suck_check_classbuffer_size(cb, 2 + 2))
618 /* class or interface type that contains the declaration of the
620 nff->class_index = suck_u2(cb);
622 /* name and descriptor of the field or method */
623 nff->nameandtype_index = suck_u2(cb);
628 case CONSTANT_Integer: {
629 constant_integer *ci = NEW(constant_integer);
631 #if defined(ENABLE_STATISTICS)
633 count_const_pool_len += sizeof(constant_integer);
636 if (!suck_check_classbuffer_size(cb, 4))
639 ci->value = suck_s4(cb);
640 cptags[idx] = CONSTANT_Integer;
647 case CONSTANT_Float: {
648 constant_float *cf = NEW(constant_float);
650 #if defined(ENABLE_STATISTICS)
652 count_const_pool_len += sizeof(constant_float);
655 if (!suck_check_classbuffer_size(cb, 4))
658 cf->value = suck_float(cb);
659 cptags[idx] = CONSTANT_Float;
666 case CONSTANT_Long: {
667 constant_long *cl = NEW(constant_long);
669 #if defined(ENABLE_STATISTICS)
671 count_const_pool_len += sizeof(constant_long);
674 if (!suck_check_classbuffer_size(cb, 8))
677 cl->value = suck_s8(cb);
678 cptags[idx] = CONSTANT_Long;
682 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
688 case CONSTANT_Double: {
689 constant_double *cd = NEW(constant_double);
691 #if defined(ENABLE_STATISTICS)
693 count_const_pool_len += sizeof(constant_double);
696 if (!suck_check_classbuffer_size(cb, 8))
699 cd->value = suck_double(cb);
700 cptags[idx] = CONSTANT_Double;
704 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
710 case CONSTANT_Utf8: {
713 /* number of bytes in the bytes array (not string-length) */
714 if (!suck_check_classbuffer_size(cb, 2))
717 length = suck_u2(cb);
718 cptags[idx] = CONSTANT_Utf8;
720 /* validate the string */
721 if (!suck_check_classbuffer_size(cb, length))
724 #ifdef ENABLE_VERIFIER
726 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
728 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
731 #endif /* ENABLE_VERIFIER */
732 /* insert utf-string into the utf-symboltable */
733 cpinfos[idx] = utf_new((char *) cb->pos, length);
735 /* skip bytes of the string (buffer size check above) */
736 suck_skip_nbytes(cb, length);
742 exceptions_throw_classformaterror(c, "Illegal constant pool type");
748 /* resolve entries in temporary structures */
750 while (forward_classes) {
752 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
756 #ifdef ENABLE_VERIFIER
757 if (opt_verify && !is_valid_name_utf(name)) {
758 exceptions_throw_classformaterror(c, "Class reference with invalid name");
761 #endif /* ENABLE_VERIFIER */
763 /* add all class references to the descriptor_pool */
765 if (!descriptor_pool_add_class(descpool, name))
768 cptags[forward_classes->thisindex] = CONSTANT_Class;
773 if (!(tc = load_class_bootstrap(name)))
776 /* link the class later, because we cannot link the class currently
778 list_add_first(&unlinkedclasses, tc);
781 /* the classref is created later */
782 cpinfos[forward_classes->thisindex] = name;
784 nfc = forward_classes;
785 forward_classes = forward_classes->next;
788 while (forward_strings) {
790 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
794 /* resolve utf-string */
795 cptags[forward_strings->thisindex] = CONSTANT_String;
796 cpinfos[forward_strings->thisindex] = text;
798 nfs = forward_strings;
799 forward_strings = forward_strings->next;
802 while (forward_nameandtypes) {
803 constant_nameandtype *cn = NEW(constant_nameandtype);
805 #if defined(ENABLE_STATISTICS)
807 count_const_pool_len += sizeof(constant_nameandtype);
810 /* resolve simple name and descriptor */
811 cn->name = class_getconstant(c,
812 forward_nameandtypes->name_index,
817 cn->descriptor = class_getconstant(c,
818 forward_nameandtypes->sig_index,
823 #ifdef ENABLE_VERIFIER
826 if (!is_valid_name_utf(cn->name)) {
827 exceptions_throw_classformaterror(c,
828 "Illegal Field name \"%s\"",
834 /* disallow referencing <clinit> among others */
835 if (cn->name->text[0] == '<' && cn->name != utf_init) {
836 exceptions_throw_classformaterror(c, "Illegal reference to special method");
840 #endif /* ENABLE_VERIFIER */
842 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
843 cpinfos[forward_nameandtypes->thisindex] = cn;
845 nfn = forward_nameandtypes;
846 forward_nameandtypes = forward_nameandtypes->next;
849 while (forward_fieldmethints) {
850 constant_nameandtype *nat;
851 constant_FMIref *fmi = NEW(constant_FMIref);
853 #if defined(ENABLE_STATISTICS)
855 count_const_pool_len += sizeof(constant_FMIref);
857 /* resolve simple name and descriptor */
859 nat = class_getconstant(c,
860 forward_fieldmethints->nameandtype_index,
861 CONSTANT_NameAndType);
865 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
867 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
870 /* the classref is created later */
872 fmi->p.index = forward_fieldmethints->class_index;
873 fmi->name = nat->name;
874 fmi->descriptor = nat->descriptor;
876 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
877 cpinfos[forward_fieldmethints->thisindex] = fmi;
879 nff = forward_fieldmethints;
880 forward_fieldmethints = forward_fieldmethints->next;
883 /* everything was ok */
889 /* loader_load_attribute_signature *********************************************
891 Signature_attribute {
892 u2 attribute_name_index;
897 *******************************************************************************/
899 #if defined(ENABLE_JAVASE)
900 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
910 /* check remaining bytecode */
912 if (!suck_check_classbuffer_size(cb, 4 + 2))
915 /* check attribute length */
917 attribute_length = suck_u4(cb);
919 if (attribute_length != 2) {
920 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
924 if (*signature != NULL) {
925 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
931 signature_index = suck_u2(cb);
933 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
938 #endif /* defined(ENABLE_JAVASE) */
941 /* load_field ******************************************************************
943 Load everything about a class field from the class file and fill a
944 'fieldinfo' structure. For static fields, space in the data segment
947 *******************************************************************************/
949 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
951 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
956 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
961 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
964 f->flags = suck_u2(cb);
966 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
971 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
975 f->parseddesc = NULL;
977 if (!descriptor_pool_add(descpool, u, NULL))
980 /* descriptor_pool_add accepts method descriptors, so we have to check */
981 /* against them here before the call of descriptor_to_basic_type below. */
982 if (u->text[0] == '(') {
983 exceptions_throw_classformaterror(c, "Method descriptor used for field");
987 #ifdef ENABLE_VERIFIER
990 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
991 exceptions_throw_classformaterror(c,
992 "Illegal Field name \"%s\"",
997 /* check flag consistency */
998 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1000 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1001 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1002 exceptions_throw_classformaterror(c,
1003 "Illegal field modifiers: 0x%X",
1008 if (c->flags & ACC_INTERFACE) {
1009 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1010 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1011 f->flags & ACC_TRANSIENT) {
1012 exceptions_throw_classformaterror(c,
1013 "Illegal field modifiers: 0x%X",
1019 #endif /* ENABLE_VERIFIER */
1021 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1022 f->offset = 0; /* offset from start of object */
1040 if (!(f->flags & ACC_STATIC))
1041 c->flags |= ACC_CLASS_HAS_POINTERS;
1049 f->value.l.high = 0;
1054 /* read attributes */
1055 if (!suck_check_classbuffer_size(cb, 2))
1058 attrnum = suck_u2(cb);
1059 for (i = 0; i < attrnum; i++) {
1060 if (!suck_check_classbuffer_size(cb, 2))
1063 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1066 if (u == utf_ConstantValue) {
1067 if (!suck_check_classbuffer_size(cb, 4 + 2))
1070 /* check attribute length */
1072 if (suck_u4(cb) != 2) {
1073 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1077 /* constant value attribute */
1079 if (pindex != field_load_NOVALUE) {
1080 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1084 /* index of value in constantpool */
1086 pindex = suck_u2(cb);
1088 /* initialize field with value from constantpool */
1091 constant_integer *ci;
1093 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1096 f->value.i = ci->value;
1103 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1106 f->value.l = cl->value;
1113 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1116 f->value.f = cf->value;
1121 constant_double *cd;
1123 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1126 f->value.d = cd->value;
1131 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1134 /* create javastring from compressed utf8-string */
1135 f->value.a = literalstring_new(u);
1139 log_text("Invalid Constant - Type");
1142 #if defined(ENABLE_JAVASE)
1143 else if (u == utf_Signature) {
1146 if (!loader_load_attribute_signature(cb, &(f->signature)))
1151 /* unknown attribute */
1153 if (!loader_skip_attribute_body(cb))
1158 /* everything was ok */
1164 /* loader_load_method **********************************************************
1166 Loads a method from the class file and fills an existing
1167 'methodinfo' structure. For native methods, the function pointer
1168 field is set to the real function pointer, for JavaVM methods a
1169 pointer to the compiler is used preliminarily.
1174 u2 descriptor_index;
1175 u2 attributes_count;
1176 attribute_info attributes[attribute_count];
1180 u2 attribute_name_index;
1181 u4 attribute_length;
1182 u1 info[attribute_length];
1185 LineNumberTable_attribute {
1186 u2 attribute_name_index;
1187 u4 attribute_length;
1188 u2 line_number_table_length;
1192 } line_number_table[line_number_table_length];
1195 *******************************************************************************/
1197 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1198 descriptor_pool *descpool)
1205 u2 descriptor_index;
1206 u2 attributes_count;
1207 u2 attribute_name_index;
1208 utf *attribute_name;
1209 u2 code_attributes_count;
1210 u2 code_attribute_name_index;
1211 utf *code_attribute_name;
1217 #if defined(ENABLE_THREADS)
1218 lock_init_object_lock(&m->header);
1221 #if defined(ENABLE_STATISTICS)
1223 count_all_methods++;
1226 /* all fields of m have been zeroed in load_class_from_classbuffer */
1230 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1235 m->flags = suck_u2(cb);
1239 name_index = suck_u2(cb);
1241 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1248 descriptor_index = suck_u2(cb);
1250 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1255 if (!descriptor_pool_add(descpool, u, &argcount))
1258 #ifdef ENABLE_VERIFIER
1260 if (!is_valid_name_utf(m->name)) {
1261 exceptions_throw_classformaterror(c, "Method with invalid name");
1265 if (m->name->text[0] == '<' &&
1266 m->name != utf_init && m->name != utf_clinit) {
1267 exceptions_throw_classformaterror(c, "Method with invalid special name");
1271 #endif /* ENABLE_VERIFIER */
1273 if (!(m->flags & ACC_STATIC))
1274 argcount++; /* count the 'this' argument */
1276 #ifdef ENABLE_VERIFIER
1278 if (argcount > 255) {
1279 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1283 /* check flag consistency */
1284 if (m->name != utf_clinit) {
1285 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1287 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1288 exceptions_throw_classformaterror(c,
1289 "Illegal method modifiers: 0x%X",
1294 if (m->flags & ACC_ABSTRACT) {
1295 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1296 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1297 exceptions_throw_classformaterror(c,
1298 "Illegal method modifiers: 0x%X",
1304 if (c->flags & ACC_INTERFACE) {
1305 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1306 exceptions_throw_classformaterror(c,
1307 "Illegal method modifiers: 0x%X",
1313 if (m->name == utf_init) {
1314 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1315 ACC_NATIVE | ACC_ABSTRACT)) {
1316 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1322 #endif /* ENABLE_VERIFIER */
1324 /* mark the method as monomorphic until further notice */
1326 m->flags |= ACC_METHOD_MONOMORPHIC;
1328 /* non-abstract methods have an implementation in this class */
1330 if (!(m->flags & ACC_ABSTRACT))
1331 m->flags |= ACC_METHOD_IMPLEMENTED;
1333 if (!suck_check_classbuffer_size(cb, 2))
1336 /* attributes count */
1338 attributes_count = suck_u2(cb);
1340 for (i = 0; i < attributes_count; i++) {
1341 if (!suck_check_classbuffer_size(cb, 2))
1344 /* attribute name index */
1346 attribute_name_index = suck_u2(cb);
1348 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1351 if (attribute_name == utf_Code) {
1353 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1354 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1359 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1363 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1367 m->maxstack = suck_u2(cb);
1368 m->maxlocals = suck_u2(cb);
1370 if (m->maxlocals < argcount) {
1371 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1375 if (!suck_check_classbuffer_size(cb, 4))
1378 m->jcodelength = suck_u4(cb);
1380 if (m->jcodelength == 0) {
1381 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1385 if (m->jcodelength > 65535) {
1386 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1390 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1393 m->jcode = MNEW(u1, m->jcodelength);
1394 suck_nbytes(m->jcode, cb, m->jcodelength);
1396 if (!suck_check_classbuffer_size(cb, 2))
1399 m->rawexceptiontablelength = suck_u2(cb);
1400 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1403 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1405 #if defined(ENABLE_STATISTICS)
1407 count_vmcode_len += m->jcodelength + 18;
1408 count_extable_len +=
1409 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1413 for (j = 0; j < m->rawexceptiontablelength; j++) {
1415 m->rawexceptiontable[j].startpc = suck_u2(cb);
1416 m->rawexceptiontable[j].endpc = suck_u2(cb);
1417 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1421 m->rawexceptiontable[j].catchtype.any = NULL;
1424 /* the classref is created later */
1425 if (!(m->rawexceptiontable[j].catchtype.any =
1426 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1431 if (!suck_check_classbuffer_size(cb, 2))
1434 /* code attributes count */
1436 code_attributes_count = suck_u2(cb);
1438 for (k = 0; k < code_attributes_count; k++) {
1439 if (!suck_check_classbuffer_size(cb, 2))
1442 /* code attribute name index */
1444 code_attribute_name_index = suck_u2(cb);
1446 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1449 /* check which code attribute */
1451 if (code_attribute_name == utf_LineNumberTable) {
1452 /* LineNumberTable */
1453 if (!suck_check_classbuffer_size(cb, 4 + 2))
1456 /* attribute length */
1460 /* line number table length */
1462 m->linenumbercount = suck_u2(cb);
1464 if (!suck_check_classbuffer_size(cb,
1465 (2 + 2) * m->linenumbercount))
1468 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1470 #if defined(ENABLE_STATISTICS)
1472 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1475 for (l = 0; l < m->linenumbercount; l++) {
1476 m->linenumbers[l].start_pc = suck_u2(cb);
1477 m->linenumbers[l].line_number = suck_u2(cb);
1480 #if defined(ENABLE_JAVASE)
1481 else if (code_attribute_name == utf_StackMapTable) {
1484 if (!stackmap_load_attribute_stackmaptable(cb, m))
1489 /* unknown code attribute */
1491 if (!loader_skip_attribute_body(cb))
1496 else if (attribute_name == utf_Exceptions) {
1499 if (m->thrownexceptions != NULL) {
1500 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1504 if (!suck_check_classbuffer_size(cb, 4 + 2))
1507 /* attribute length */
1511 m->thrownexceptionscount = suck_u2(cb);
1513 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1516 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1518 for (j = 0; j < m->thrownexceptionscount; j++) {
1519 /* the classref is created later */
1520 if (!((m->thrownexceptions)[j].any =
1521 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1525 #if defined(ENABLE_JAVASE)
1526 else if (attribute_name == utf_Signature) {
1529 if (!loader_load_attribute_signature(cb, &(m->signature)))
1534 /* unknown attribute */
1536 if (!loader_skip_attribute_body(cb))
1541 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1542 exceptions_throw_classformaterror(c, "Missing Code attribute");
1546 /* initialize the hit countdown field */
1548 #if defined(ENABLE_REPLACEMENT)
1549 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1552 /* everything was ok */
1558 /* load_class_from_sysloader ***************************************************
1560 Load the class with the given name using the system class loader
1563 name.............the classname
1566 the loaded class, or
1567 NULL if an exception has been thrown
1569 *******************************************************************************/
1571 classinfo *load_class_from_sysloader(utf *name)
1574 java_objectheader *clo;
1578 assert(class_java_lang_Object);
1579 assert(class_java_lang_ClassLoader);
1580 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1582 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1583 utf_getSystemClassLoader,
1584 utf_void__java_lang_ClassLoader,
1585 class_java_lang_Object,
1591 clo = vm_call_method(m, NULL);
1596 cl = loader_hashtable_classloader_add(clo);
1598 c = load_class_from_classloader(name, cl);
1604 /* load_class_from_classloader *************************************************
1606 Load the class with the given name using the given user-defined class loader.
1609 name.............the classname
1610 cl...............user-defined class loader
1613 the loaded class, or
1614 NULL if an exception has been thrown
1616 *******************************************************************************/
1618 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1620 java_objectheader *o;
1623 java_objectheader *string;
1624 #if defined(ENABLE_RT_TIMING)
1625 struct timespec time_start, time_lookup, time_prepare, time_java,
1629 RT_TIMING_GET_TIME(time_start);
1633 /* lookup if this class has already been loaded */
1635 c = classcache_lookup(cl, name);
1637 RT_TIMING_GET_TIME(time_lookup);
1638 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1643 /* if other class loader than bootstrap, call it */
1651 namelen = name->blength;
1653 /* handle array classes */
1654 if (text[0] == '[') {
1660 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1661 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1662 exceptions_throw_noclassdeffounderror(name);
1666 u = utf_new(text + 2, namelen - 3);
1668 if (!(comp = load_class_from_classloader(u, cl)))
1671 /* create the array class */
1673 c = class_array_of(comp, false);
1675 tmpc = classcache_store(cl, c, true);
1678 /* exception, free the loaded class */
1679 c->state &= ~CLASS_LOADING;
1686 /* load the component class */
1688 u = utf_new(text + 1, namelen - 1);
1690 if (!(comp = load_class_from_classloader(u, cl)))
1693 /* create the array class */
1695 c = class_array_of(comp, false);
1697 tmpc = classcache_store(cl, c, true);
1700 /* exception, free the loaded class */
1701 c->state &= ~CLASS_LOADING;
1708 /* primitive array classes are loaded by the bootstrap loader */
1710 c = load_class_bootstrap(name);
1716 assert(class_java_lang_Object);
1718 lc = class_resolveclassmethod(cl->object->vftbl->class,
1720 utf_java_lang_String__java_lang_Class,
1721 class_java_lang_Object,
1725 return false; /* exception */
1727 /* move return value into `o' and cast it afterwards to a classinfo* */
1729 string = javastring_new_slash_to_dot(name);
1731 RT_TIMING_GET_TIME(time_prepare);
1733 o = vm_call_method(lc, cl->object, string);
1735 RT_TIMING_GET_TIME(time_java);
1737 c = (classinfo *) o;
1740 /* Store this class in the loaded class cache. If another
1741 class with the same (initloader,name) pair has been
1742 stored earlier it will be returned by classcache_store
1743 In this case classcache_store may not free the class
1744 because it has already been exposed to Java code which
1745 may have kept references to that class. */
1747 tmpc = classcache_store(cl, c, false);
1750 /* exception, free the loaded class */
1751 c->state &= ~CLASS_LOADING;
1758 /* loadClass has thrown an exception. We must convert
1759 ClassNotFoundException into
1760 NoClassDefFoundException. */
1762 /* XXX Maybe we should have a flag that avoids this
1763 conversion for calling load_class_from_classloader from
1764 Class.forName. Currently we do a double conversion in
1767 classnotfoundexception_to_noclassdeffounderror();
1770 RT_TIMING_GET_TIME(time_cache);
1772 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1773 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1774 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1776 /* SUN compatible -verbose:class output */
1778 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1780 utf_display_printable_ascii_classname(name);
1784 #if defined(ENABLE_JVMTI)
1785 /* fire Class Load JVMTI event */
1786 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1793 c = load_class_bootstrap(name);
1799 /* load_class_bootstrap ********************************************************
1801 Load the class with the given name using the bootstrap class loader.
1804 name.............the classname
1807 loaded classinfo, or
1808 NULL if an exception has been thrown
1811 load_class_bootstrap is synchronized. It can be treated as an
1814 *******************************************************************************/
1816 classinfo *load_class_bootstrap(utf *name)
1821 #if defined(ENABLE_RT_TIMING)
1822 struct timespec time_start, time_lookup, time_array, time_suck,
1823 time_load, time_cache;
1826 RT_TIMING_GET_TIME(time_start);
1832 /* lookup if this class has already been loaded */
1834 if ((r = classcache_lookup(NULL, name))) {
1836 RT_TIMING_GET_TIME(time_lookup);
1837 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1842 RT_TIMING_GET_TIME(time_lookup);
1843 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1845 /* create the classinfo */
1847 c = class_create_classinfo(name);
1849 /* handle array classes */
1851 if (name->text[0] == '[') {
1852 c = load_newly_created_array(c, NULL);
1855 assert(c->state & CLASS_LOADED);
1857 RT_TIMING_GET_TIME(time_array);
1858 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1863 #if defined(ENABLE_STATISTICS)
1866 if (opt_getcompilingtime)
1867 compilingtime_stop();
1869 if (opt_getloadingtime)
1870 loadingtime_start();
1873 /* load classdata, throw exception on error */
1878 /* this normally means, the classpath was not set properly */
1880 if (name == utf_java_lang_Object)
1881 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1883 exceptions_throw_noclassdeffounderror(name);
1888 RT_TIMING_GET_TIME(time_suck);
1890 /* load the class from the buffer */
1892 r = load_class_from_classbuffer(cb);
1894 RT_TIMING_GET_TIME(time_load);
1897 /* the class could not be loaded, free the classinfo struct */
1902 /* Store this class in the loaded class cache this step also
1903 checks the loading constraints. If the class has been loaded
1904 before, the earlier loaded class is returned. */
1906 classinfo *res = classcache_store(NULL, c, true);
1916 RT_TIMING_GET_TIME(time_cache);
1918 /* SUN compatible -verbose:class output */
1920 if (opt_verboseclass && r) {
1922 utf_display_printable_ascii_classname(name);
1923 printf(" from %s]\n", cb->path);
1930 #if defined(ENABLE_STATISTICS)
1933 if (opt_getloadingtime)
1936 if (opt_getcompilingtime)
1937 compilingtime_start();
1940 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1941 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1942 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1943 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1949 /* load_class_from_classbuffer *************************************************
1951 Loads everything interesting about a class from the class file. The
1952 'classinfo' structure must have been allocated previously.
1954 The super class and the interfaces implemented by this class need
1955 not be loaded. The link is set later by the function 'class_link'.
1957 The loaded class is removed from the list 'unloadedclasses' and
1958 added to the list 'unlinkedclasses'.
1961 This function is NOT synchronized!
1963 *******************************************************************************/
1965 classinfo *load_class_from_classbuffer(classbuffer *cb)
1973 descriptor_pool *descpool;
1974 #if defined(ENABLE_STATISTICS)
1978 #if defined(ENABLE_RT_TIMING)
1979 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1980 time_setup, time_fields, time_methods, time_classrefs,
1981 time_descs, time_setrefs, time_parsefds, time_parsemds,
1982 time_parsecpool, time_verify, time_attrs;
1985 RT_TIMING_GET_TIME(time_start);
1987 /* get the classbuffer's class */
1991 /* the class is already loaded */
1993 if (c->state & CLASS_LOADED)
1996 #if defined(ENABLE_STATISTICS)
1998 count_class_loads++;
2001 #if !defined(NDEBUG)
2002 /* output for debugging purposes */
2005 log_message_class("Loading class: ", c);
2008 /* mark start of dump memory area */
2010 dumpsize = dump_size();
2012 /* class is currently loading */
2014 c->state |= CLASS_LOADING;
2016 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2017 goto return_exception;
2019 /* check signature */
2021 if (suck_u4(cb) != MAGIC) {
2022 exceptions_throw_classformaterror(c, "Bad magic number");
2024 goto return_exception;
2032 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2033 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2034 goto return_exception;
2037 RT_TIMING_GET_TIME(time_checks);
2039 /* create a new descriptor pool */
2041 descpool = descriptor_pool_new(c);
2043 RT_TIMING_GET_TIME(time_ndpool);
2045 /* load the constant pool */
2047 if (!load_constantpool(cb, descpool))
2048 goto return_exception;
2050 RT_TIMING_GET_TIME(time_cpool);
2054 if (!suck_check_classbuffer_size(cb, 2))
2055 goto return_exception;
2057 /* We OR the flags here, as we set already some flags in
2058 class_create_classinfo. */
2060 c->flags |= suck_u2(cb);
2062 /* check ACC flags consistency */
2064 if (c->flags & ACC_INTERFACE) {
2065 if (!(c->flags & ACC_ABSTRACT)) {
2066 /* We work around this because interfaces in JDK 1.1 are
2067 * not declared abstract. */
2069 c->flags |= ACC_ABSTRACT;
2072 if (c->flags & ACC_FINAL) {
2073 exceptions_throw_classformaterror(c,
2074 "Illegal class modifiers: 0x%X",
2076 goto return_exception;
2079 if (c->flags & ACC_SUPER) {
2080 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2084 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2085 exceptions_throw_classformaterror(c,
2086 "Illegal class modifiers: 0x%X",
2088 goto return_exception;
2091 if (!suck_check_classbuffer_size(cb, 2 + 2))
2092 goto return_exception;
2098 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2099 goto return_exception;
2101 if (c->name == utf_not_named_yet) {
2102 /* we finally have a name for this class */
2104 class_set_packagename(c);
2106 else if (name != c->name) {
2107 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
2108 goto return_exception;
2111 /* retrieve superclass */
2113 c->super.any = NULL;
2115 if ((i = suck_u2(cb))) {
2116 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2117 goto return_exception;
2119 /* java.lang.Object may not have a super class. */
2121 if (c->name == utf_java_lang_Object) {
2122 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2123 goto return_exception;
2126 /* Interfaces must have java.lang.Object as super class. */
2128 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2129 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2130 goto return_exception;
2136 /* This is only allowed for java.lang.Object. */
2138 if (c->name != utf_java_lang_Object) {
2139 exceptions_throw_classformaterror(c, "Bad superclass index");
2140 goto return_exception;
2144 /* retrieve interfaces */
2146 if (!suck_check_classbuffer_size(cb, 2))
2147 goto return_exception;
2149 c->interfacescount = suck_u2(cb);
2151 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2152 goto return_exception;
2154 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2155 for (i = 0; i < c->interfacescount; i++) {
2156 /* the classrefs are created later */
2157 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2158 goto return_exception;
2161 RT_TIMING_GET_TIME(time_setup);
2164 if (!suck_check_classbuffer_size(cb, 2))
2165 goto return_exception;
2167 c->fieldscount = suck_u2(cb);
2168 #if defined(ENABLE_GC_CACAO)
2169 c->fields = MNEW(fieldinfo, c->fieldscount);
2170 MZERO(c->fields, fieldinfo, c->fieldscount);
2172 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2175 for (i = 0; i < c->fieldscount; i++) {
2176 if (!load_field(cb, &(c->fields[i]),descpool))
2177 goto return_exception;
2180 RT_TIMING_GET_TIME(time_fields);
2183 if (!suck_check_classbuffer_size(cb, 2))
2184 goto return_exception;
2186 c->methodscount = suck_u2(cb);
2187 c->methods = MNEW(methodinfo, c->methodscount);
2189 MZERO(c->methods, methodinfo, c->methodscount);
2191 for (i = 0; i < c->methodscount; i++) {
2192 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2193 goto return_exception;
2196 RT_TIMING_GET_TIME(time_methods);
2198 /* create the class reference table */
2201 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2203 RT_TIMING_GET_TIME(time_classrefs);
2205 /* allocate space for the parsed descriptors */
2207 descriptor_pool_alloc_parsed_descriptors(descpool);
2209 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2211 #if defined(ENABLE_STATISTICS)
2213 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2214 count_classref_len += classrefsize;
2215 count_parsed_desc_len += descsize;
2219 RT_TIMING_GET_TIME(time_descs);
2221 /* put the classrefs in the constant pool */
2222 for (i = 0; i < c->cpcount; i++) {
2223 if (c->cptags[i] == CONSTANT_Class) {
2224 utf *name = (utf *) c->cpinfos[i];
2225 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2229 /* set the super class reference */
2232 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2234 goto return_exception;
2237 /* set the super interfaces references */
2239 for (i = 0; i < c->interfacescount; i++) {
2240 c->interfaces[i].ref =
2241 descriptor_pool_lookup_classref(descpool,
2242 (utf *) c->interfaces[i].any);
2243 if (!c->interfaces[i].ref)
2244 goto return_exception;
2247 RT_TIMING_GET_TIME(time_setrefs);
2249 /* parse field descriptors */
2251 for (i = 0; i < c->fieldscount; i++) {
2252 c->fields[i].parseddesc =
2253 descriptor_pool_parse_field_descriptor(descpool,
2254 c->fields[i].descriptor);
2255 if (!c->fields[i].parseddesc)
2256 goto return_exception;
2259 RT_TIMING_GET_TIME(time_parsefds);
2261 /* parse method descriptors */
2263 for (i = 0; i < c->methodscount; i++) {
2264 methodinfo *m = &c->methods[i];
2266 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2267 m->flags, class_get_self_classref(m->class));
2269 goto return_exception;
2271 for (j = 0; j < m->rawexceptiontablelength; j++) {
2272 if (!m->rawexceptiontable[j].catchtype.any)
2274 if ((m->rawexceptiontable[j].catchtype.ref =
2275 descriptor_pool_lookup_classref(descpool,
2276 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2277 goto return_exception;
2280 for (j = 0; j < m->thrownexceptionscount; j++) {
2281 if (!m->thrownexceptions[j].any)
2283 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2284 (utf *) m->thrownexceptions[j].any)) == NULL)
2285 goto return_exception;
2289 RT_TIMING_GET_TIME(time_parsemds);
2291 /* parse the loaded descriptors */
2293 for (i = 0; i < c->cpcount; i++) {
2294 constant_FMIref *fmi;
2297 switch (c->cptags[i]) {
2298 case CONSTANT_Fieldref:
2299 fmi = (constant_FMIref *) c->cpinfos[i];
2300 fmi->parseddesc.fd =
2301 descriptor_pool_parse_field_descriptor(descpool,
2303 if (!fmi->parseddesc.fd)
2304 goto return_exception;
2305 index = fmi->p.index;
2307 (constant_classref *) class_getconstant(c, index,
2309 if (!fmi->p.classref)
2310 goto return_exception;
2312 case CONSTANT_Methodref:
2313 case CONSTANT_InterfaceMethodref:
2314 fmi = (constant_FMIref *) c->cpinfos[i];
2315 index = fmi->p.index;
2317 (constant_classref *) class_getconstant(c, index,
2319 if (!fmi->p.classref)
2320 goto return_exception;
2321 fmi->parseddesc.md =
2322 descriptor_pool_parse_method_descriptor(descpool,
2326 if (!fmi->parseddesc.md)
2327 goto return_exception;
2332 RT_TIMING_GET_TIME(time_parsecpool);
2334 #ifdef ENABLE_VERIFIER
2335 /* Check if all fields and methods can be uniquely
2336 * identified by (name,descriptor). */
2339 /* We use a hash table here to avoid making the
2340 * average case quadratic in # of methods, fields.
2342 static int shift = 0;
2344 u2 *next; /* for chaining colliding hash entries */
2350 /* Allocate hashtable */
2351 len = c->methodscount;
2352 if (len < c->fieldscount) len = c->fieldscount;
2354 hashtab = MNEW(u2,(hashlen + len));
2355 next = hashtab + hashlen;
2357 /* Determine bitshift (to get good hash values) */
2367 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2369 for (i = 0; i < c->fieldscount; ++i) {
2370 fieldinfo *fi = c->fields + i;
2372 /* It's ok if we lose bits here */
2373 index = ((((size_t) fi->name) +
2374 ((size_t) fi->descriptor)) >> shift) % hashlen;
2376 if ((old = hashtab[index])) {
2380 if (c->fields[old].name == fi->name &&
2381 c->fields[old].descriptor == fi->descriptor) {
2382 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2383 goto return_exception;
2385 } while ((old = next[old]));
2387 hashtab[index] = i + 1;
2391 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2393 for (i = 0; i < c->methodscount; ++i) {
2394 methodinfo *mi = c->methods + i;
2396 /* It's ok if we lose bits here */
2397 index = ((((size_t) mi->name) +
2398 ((size_t) mi->descriptor)) >> shift) % hashlen;
2402 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2403 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2407 if ((old = hashtab[index])) {
2411 if (c->methods[old].name == mi->name &&
2412 c->methods[old].descriptor == mi->descriptor) {
2413 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2414 goto return_exception;
2416 } while ((old = next[old]));
2418 hashtab[index] = i + 1;
2421 MFREE(hashtab, u2, (hashlen + len));
2423 #endif /* ENABLE_VERIFIER */
2425 RT_TIMING_GET_TIME(time_verify);
2427 #if defined(ENABLE_STATISTICS)
2429 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2430 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2431 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2435 /* load attribute structures */
2437 if (!class_load_attributes(cb))
2438 goto return_exception;
2440 /* Pre Java 1.5 version don't check this. This implementation is like
2441 Java 1.5 do it: for class file version 45.3 we don't check it, older
2442 versions are checked.
2445 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2446 /* check if all data has been read */
2447 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2449 if (classdata_left > 0) {
2450 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2451 goto return_exception;
2455 RT_TIMING_GET_TIME(time_attrs);
2457 /* release dump area */
2459 dump_release(dumpsize);
2461 /* revert loading state and class is loaded */
2463 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2465 #if defined(ENABLE_JVMTI)
2466 /* fire Class Prepare JVMTI event */
2469 jvmti_ClassLoadPrepare(true, c);
2472 #if !defined(NDEBUG)
2474 log_message_class("Loading done class: ", c);
2477 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2478 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2479 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2480 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2481 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2482 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2483 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2484 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2485 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2486 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2487 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2488 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2489 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2490 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2491 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2496 /* release dump area */
2498 dump_release(dumpsize);
2500 /* an exception has been thrown */
2506 /* load_newly_created_array ****************************************************
2508 Load a newly created array class.
2511 c....................the array class C has been loaded
2512 other classinfo......the array class was found in the class cache,
2514 NULL.................an exception has been thrown
2517 This is an internal function. Do not use it unless you know exactly
2520 Use one of the load_class_... functions for general array class loading.
2522 *******************************************************************************/
2524 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2526 classinfo *comp = NULL;
2528 methoddesc *clonedesc;
2529 constant_classref *classrefs;
2534 text = c->name->text;
2535 namelen = c->name->blength;
2537 /* Check array class name */
2539 if ((namelen < 2) || (text[0] != '[')) {
2540 exceptions_throw_noclassdeffounderror(c->name);
2544 /* Check the element type */
2548 /* c is an array of arrays. We have to create the component class. */
2550 u = utf_new(text + 1, namelen - 1);
2551 if (!(comp = load_class_from_classloader(u, loader)))
2554 assert(comp->state & CLASS_LOADED);
2560 /* the array's flags are that of the component class */
2561 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2562 c->classloader = comp->classloader;
2566 /* c is an array of objects. */
2568 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2569 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2570 exceptions_throw_noclassdeffounderror(c->name);
2574 u = utf_new(text + 2, namelen - 3);
2576 if (!(comp = load_class_from_classloader(u, loader)))
2579 assert(comp->state & CLASS_LOADED);
2585 /* the array's flags are that of the component class */
2586 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2587 c->classloader = comp->classloader;
2591 /* c is an array of a primitive type */
2593 /* check for cases like `[II' */
2595 exceptions_throw_noclassdeffounderror(c->name);
2599 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2600 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2601 c->classloader = NULL;
2604 assert(class_java_lang_Object);
2605 #if defined(ENABLE_JAVASE)
2606 assert(class_java_lang_Cloneable);
2607 assert(class_java_io_Serializable);
2610 /* setup the array class */
2612 c->super.cls = class_java_lang_Object;
2614 #if defined(ENABLE_JAVASE)
2615 c->interfacescount = 2;
2616 c->interfaces = MNEW(classref_or_classinfo, 2);
2621 tc = class_java_lang_Cloneable;
2622 assert(tc->state & CLASS_LOADED);
2623 list_add_first(&unlinkedclasses, tc);
2624 c->interfaces[0].cls = tc;
2626 tc = class_java_io_Serializable;
2627 assert(tc->state & CLASS_LOADED);
2628 list_add_first(&unlinkedclasses, tc);
2629 c->interfaces[1].cls = tc;
2632 c->interfaces[0].cls = class_java_lang_Cloneable;
2633 c->interfaces[1].cls = class_java_io_Serializable;
2635 #elif defined(ENABLE_JAVAME_CLDC1_1)
2636 c->interfacescount = 0;
2637 c->interfaces = NULL;
2639 #error unknow Java configuration
2642 c->methodscount = 1;
2643 c->methods = MNEW(methodinfo, c->methodscount);
2644 MZERO(c->methods, methodinfo, c->methodscount);
2646 classrefs = MNEW(constant_classref, 2);
2647 CLASSREF_INIT(classrefs[0], c, c->name);
2648 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2650 /* create descriptor for clone method */
2651 /* we need one paramslot which is reserved for the 'this' parameter */
2652 clonedesc = NEW(methoddesc);
2653 clonedesc->returntype.type = TYPE_ADR;
2654 clonedesc->returntype.classref = classrefs + 1;
2655 clonedesc->returntype.arraydim = 0;
2656 /* initialize params to "empty", add real params below in
2657 descriptor_params_from_paramtypes */
2658 clonedesc->paramcount = 0;
2659 clonedesc->paramslots = 0;
2660 clonedesc->paramtypes[0].classref = classrefs + 0;
2661 clonedesc->params = NULL;
2663 /* create methodinfo */
2666 MSET(clone, 0, methodinfo, 1);
2668 #if defined(ENABLE_THREADS)
2669 lock_init_object_lock(&clone->header);
2672 /* ATTENTION: if you delete the ACC_NATIVE below, set
2673 clone->maxlocals=1 (interpreter related) */
2675 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2676 clone->name = utf_clone;
2677 clone->descriptor = utf_void__java_lang_Object;
2678 clone->parseddesc = clonedesc;
2681 /* parse the descriptor to get the register allocation */
2683 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2686 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2688 /* XXX: field: length? */
2690 /* array classes are not loaded from class files */
2692 c->state |= CLASS_LOADED;
2693 c->parseddescs = (u1 *) clonedesc;
2694 c->parseddescsize = sizeof(methodinfo);
2695 c->classrefs = classrefs;
2696 c->classrefcount = 1;
2698 /* insert class into the loaded class cache */
2699 /* XXX free classinfo if NULL returned? */
2701 return classcache_store(loader, c, true);
2705 /* loader_close ****************************************************************
2707 Frees all resources.
2709 *******************************************************************************/
2711 void loader_close(void)
2718 * These are local overrides for various environment variables in Emacs.
2719 * Please do not remove this and leave it at the end of the file, where
2720 * Emacs will automagically detect them.
2721 * ---------------------------------------------------------------------
2724 * indent-tabs-mode: t
2728 * vim:noexpandtab:sw=4:ts=4: