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 7577 2007-03-25 20:55:06Z twisti $
38 #include "mm/memory.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
44 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit_interface.h"
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
59 #include "vmcore/classcache.h"
60 #include "vmcore/linker.h"
61 #include "vmcore/loader.h"
62 #include "vmcore/options.h"
63 #include "vmcore/rt-timing.h"
65 #if defined(ENABLE_STATISTICS)
66 # include "vmcore/statistics.h"
69 #include "vmcore/suck.h"
71 #if defined(ENABLE_ZLIB)
72 # include "vmcore/zip.h"
75 #if defined(ENABLE_JVMTI)
76 # include "native/jvmti/cacaodbg.h"
80 /* loader_init *****************************************************************
82 Initializes all lists and loads all classes required for the system
85 *******************************************************************************/
87 bool loader_init(void)
89 #if defined(ENABLE_THREADS)
90 list_classpath_entry *lce;
92 /* Initialize the monitor pointer for zip/jar file locking. */
94 for (lce = list_first(list_classpath_entries); lce != NULL;
95 lce = list_next(list_classpath_entries, lce))
96 if (lce->type == CLASSPATH_ARCHIVE)
97 lock_init_object_lock((java_objectheader *) lce);
100 /* load some important classes */
102 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
105 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
108 #if defined(ENABLE_JAVASE)
109 if (!(class_java_lang_Cloneable =
110 load_class_bootstrap(utf_java_lang_Cloneable)))
113 if (!(class_java_io_Serializable =
114 load_class_bootstrap(utf_java_io_Serializable)))
118 /* load classes for wrapping primitive types */
120 #if defined(ENABLE_JAVASE)
121 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
125 if (!(class_java_lang_Boolean =
126 load_class_bootstrap(utf_java_lang_Boolean)))
129 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
132 if (!(class_java_lang_Character =
133 load_class_bootstrap(utf_java_lang_Character)))
136 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
139 if (!(class_java_lang_Integer =
140 load_class_bootstrap(utf_java_lang_Integer)))
143 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
146 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
149 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
153 /* load some other important classes */
155 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
158 #if defined(ENABLE_JAVASE)
159 if (!(class_java_lang_ClassLoader =
160 load_class_bootstrap(utf_java_lang_ClassLoader)))
163 if (!(class_java_lang_SecurityManager =
164 load_class_bootstrap(utf_java_lang_SecurityManager)))
168 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
171 if (!(class_java_lang_Thread =
172 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
175 #if defined(ENABLE_JAVASE)
176 if (!(class_java_lang_ThreadGroup =
177 load_class_bootstrap(utf_java_lang_ThreadGroup)))
181 #if defined(WITH_CLASSPATH_GNU)
182 if (!(class_java_lang_VMSystem =
183 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
187 if (!(class_java_lang_VMThread =
188 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
193 /* some classes which may be used more often */
195 #if defined(ENABLE_JAVASE)
196 if (!(class_java_lang_StackTraceElement =
197 load_class_bootstrap(utf_java_lang_StackTraceElement)))
200 if (!(class_java_lang_reflect_Constructor =
201 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
204 if (!(class_java_lang_reflect_Field =
205 load_class_bootstrap(utf_java_lang_reflect_Field)))
208 if (!(class_java_lang_reflect_Method =
209 load_class_bootstrap(utf_java_lang_reflect_Method)))
212 if (!(class_java_security_PrivilegedAction =
213 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
216 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
219 if (!(arrayclass_java_lang_Object =
220 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
228 /* loader_load_all_classes *****************************************************
230 Loads all classes specified in the BOOTCLASSPATH.
232 *******************************************************************************/
234 void loader_load_all_classes(void)
236 list_classpath_entry *lce;
237 #if defined(ENABLE_ZLIB)
240 hashtable_zipfile_entry *htzfe;
244 for (lce = list_first(list_classpath_entries); lce != NULL;
245 lce = list_next(list_classpath_entries, lce)) {
246 #if defined(ENABLE_ZLIB)
247 if (lce->type == CLASSPATH_ARCHIVE) {
248 /* get the classes hashtable */
252 for (slot = 0; slot < ht->size; slot++) {
253 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
255 for (; htzfe; htzfe = htzfe->hashlink) {
258 /* skip all entries in META-INF and .properties,
261 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
262 strstr(u->text, ".properties") ||
263 strstr(u->text, ".png"))
266 /* load class from bootstrap classloader */
268 if (!load_class_bootstrap(u)) {
269 fprintf(stderr, "Error loading: ");
270 utf_fprint_printable_ascii_classname(stderr, u);
271 fprintf(stderr, "\n");
274 /* print out exception and cause */
276 exceptions_print_current_exception();
284 #if defined(ENABLE_ZLIB)
291 /* loader_skip_attribute_body **************************************************
293 Skips an attribute the attribute_name_index has already been read.
296 u2 attribute_name_index;
298 u1 info[attribute_length];
301 *******************************************************************************/
303 bool loader_skip_attribute_body(classbuffer *cb)
307 if (!suck_check_classbuffer_size(cb, 4))
310 attribute_length = suck_u4(cb);
312 if (!suck_check_classbuffer_size(cb, attribute_length))
315 suck_skip_nbytes(cb, attribute_length);
321 /* load_constantpool ***********************************************************
323 Loads the constantpool of a class, the entries are transformed into
324 a simpler format by resolving references (a detailed overview of
325 the compact structures can be found in global.h).
327 *******************************************************************************/
329 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
332 /* The following structures are used to save information which cannot be
333 processed during the first pass. After the complete constantpool has
334 been traversed the references can be resolved.
335 (only in specific order) */
337 /* CONSTANT_Class entries */
338 typedef struct forward_class {
339 struct forward_class *next;
344 /* CONSTANT_String */
345 typedef struct forward_string {
346 struct forward_string *next;
351 /* CONSTANT_NameAndType */
352 typedef struct forward_nameandtype {
353 struct forward_nameandtype *next;
357 } forward_nameandtype;
359 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
360 typedef struct forward_fieldmethint {
361 struct forward_fieldmethint *next;
365 u2 nameandtype_index;
366 } forward_fieldmethint;
372 forward_class *forward_classes = NULL;
373 forward_string *forward_strings = NULL;
374 forward_nameandtype *forward_nameandtypes = NULL;
375 forward_fieldmethint *forward_fieldmethints = NULL;
379 forward_nameandtype *nfn;
380 forward_fieldmethint *nff;
388 /* number of entries in the constant_pool table plus one */
389 if (!suck_check_classbuffer_size(cb, 2))
392 cpcount = c->cpcount = suck_u2(cb);
394 /* allocate memory */
395 cptags = c->cptags = MNEW(u1, cpcount);
396 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
399 exceptions_throw_classformaterror(c, "Illegal constant pool size");
403 #if defined(ENABLE_STATISTICS)
405 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
408 /* initialize constantpool */
409 for (idx = 0; idx < cpcount; idx++) {
410 cptags[idx] = CONSTANT_UNUSED;
415 /******* first pass *******/
416 /* entries which cannot be resolved now are written into
417 temporary structures and traversed again later */
420 while (idx < cpcount) {
423 /* get constant type */
424 if (!suck_check_classbuffer_size(cb, 1))
431 nfc = DNEW(forward_class);
433 nfc->next = forward_classes;
434 forward_classes = nfc;
436 nfc->thisindex = idx;
437 /* reference to CONSTANT_NameAndType */
438 if (!suck_check_classbuffer_size(cb, 2))
441 nfc->name_index = suck_u2(cb);
446 case CONSTANT_String:
447 nfs = DNEW(forward_string);
449 nfs->next = forward_strings;
450 forward_strings = nfs;
452 nfs->thisindex = idx;
454 /* reference to CONSTANT_Utf8_info with string characters */
455 if (!suck_check_classbuffer_size(cb, 2))
458 nfs->string_index = suck_u2(cb);
463 case CONSTANT_NameAndType:
464 nfn = DNEW(forward_nameandtype);
466 nfn->next = forward_nameandtypes;
467 forward_nameandtypes = nfn;
469 nfn->thisindex = idx;
471 if (!suck_check_classbuffer_size(cb, 2 + 2))
474 /* reference to CONSTANT_Utf8_info containing simple name */
475 nfn->name_index = suck_u2(cb);
477 /* reference to CONSTANT_Utf8_info containing field or method
479 nfn->sig_index = suck_u2(cb);
484 case CONSTANT_Fieldref:
485 case CONSTANT_Methodref:
486 case CONSTANT_InterfaceMethodref:
487 nff = DNEW(forward_fieldmethint);
489 nff->next = forward_fieldmethints;
490 forward_fieldmethints = nff;
492 nff->thisindex = idx;
496 if (!suck_check_classbuffer_size(cb, 2 + 2))
499 /* class or interface type that contains the declaration of the
501 nff->class_index = suck_u2(cb);
503 /* name and descriptor of the field or method */
504 nff->nameandtype_index = suck_u2(cb);
509 case CONSTANT_Integer: {
510 constant_integer *ci = NEW(constant_integer);
512 #if defined(ENABLE_STATISTICS)
514 count_const_pool_len += sizeof(constant_integer);
517 if (!suck_check_classbuffer_size(cb, 4))
520 ci->value = suck_s4(cb);
521 cptags[idx] = CONSTANT_Integer;
528 case CONSTANT_Float: {
529 constant_float *cf = NEW(constant_float);
531 #if defined(ENABLE_STATISTICS)
533 count_const_pool_len += sizeof(constant_float);
536 if (!suck_check_classbuffer_size(cb, 4))
539 cf->value = suck_float(cb);
540 cptags[idx] = CONSTANT_Float;
547 case CONSTANT_Long: {
548 constant_long *cl = NEW(constant_long);
550 #if defined(ENABLE_STATISTICS)
552 count_const_pool_len += sizeof(constant_long);
555 if (!suck_check_classbuffer_size(cb, 8))
558 cl->value = suck_s8(cb);
559 cptags[idx] = CONSTANT_Long;
563 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
569 case CONSTANT_Double: {
570 constant_double *cd = NEW(constant_double);
572 #if defined(ENABLE_STATISTICS)
574 count_const_pool_len += sizeof(constant_double);
577 if (!suck_check_classbuffer_size(cb, 8))
580 cd->value = suck_double(cb);
581 cptags[idx] = CONSTANT_Double;
585 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
591 case CONSTANT_Utf8: {
594 /* number of bytes in the bytes array (not string-length) */
595 if (!suck_check_classbuffer_size(cb, 2))
598 length = suck_u2(cb);
599 cptags[idx] = CONSTANT_Utf8;
601 /* validate the string */
602 if (!suck_check_classbuffer_size(cb, length))
605 #ifdef ENABLE_VERIFIER
607 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
609 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
612 #endif /* ENABLE_VERIFIER */
613 /* insert utf-string into the utf-symboltable */
614 cpinfos[idx] = utf_new((char *) cb->pos, length);
616 /* skip bytes of the string (buffer size check above) */
617 suck_skip_nbytes(cb, length);
623 exceptions_throw_classformaterror(c, "Illegal constant pool type");
629 /* resolve entries in temporary structures */
631 while (forward_classes) {
633 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
637 #ifdef ENABLE_VERIFIER
638 if (opt_verify && !is_valid_name_utf(name)) {
639 exceptions_throw_classformaterror(c, "Class reference with invalid name");
642 #endif /* ENABLE_VERIFIER */
644 /* add all class references to the descriptor_pool */
646 if (!descriptor_pool_add_class(descpool, name))
649 cptags[forward_classes->thisindex] = CONSTANT_Class;
654 if (!(tc = load_class_bootstrap(name)))
657 /* link the class later, because we cannot link the class currently
659 list_add_first(&unlinkedclasses, tc);
662 /* the classref is created later */
663 cpinfos[forward_classes->thisindex] = name;
665 nfc = forward_classes;
666 forward_classes = forward_classes->next;
669 while (forward_strings) {
671 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
675 /* resolve utf-string */
676 cptags[forward_strings->thisindex] = CONSTANT_String;
677 cpinfos[forward_strings->thisindex] = text;
679 nfs = forward_strings;
680 forward_strings = forward_strings->next;
683 while (forward_nameandtypes) {
684 constant_nameandtype *cn = NEW(constant_nameandtype);
686 #if defined(ENABLE_STATISTICS)
688 count_const_pool_len += sizeof(constant_nameandtype);
691 /* resolve simple name and descriptor */
692 cn->name = class_getconstant(c,
693 forward_nameandtypes->name_index,
698 cn->descriptor = class_getconstant(c,
699 forward_nameandtypes->sig_index,
704 #ifdef ENABLE_VERIFIER
707 if (!is_valid_name_utf(cn->name)) {
708 exceptions_throw_classformaterror(c,
709 "Illegal Field name \"%s\"",
715 /* disallow referencing <clinit> among others */
716 if (cn->name->text[0] == '<' && cn->name != utf_init) {
717 exceptions_throw_classformaterror(c, "Illegal reference to special method");
721 #endif /* ENABLE_VERIFIER */
723 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
724 cpinfos[forward_nameandtypes->thisindex] = cn;
726 nfn = forward_nameandtypes;
727 forward_nameandtypes = forward_nameandtypes->next;
730 while (forward_fieldmethints) {
731 constant_nameandtype *nat;
732 constant_FMIref *fmi = NEW(constant_FMIref);
734 #if defined(ENABLE_STATISTICS)
736 count_const_pool_len += sizeof(constant_FMIref);
738 /* resolve simple name and descriptor */
740 nat = class_getconstant(c,
741 forward_fieldmethints->nameandtype_index,
742 CONSTANT_NameAndType);
746 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
748 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
751 /* the classref is created later */
753 fmi->p.index = forward_fieldmethints->class_index;
754 fmi->name = nat->name;
755 fmi->descriptor = nat->descriptor;
757 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
758 cpinfos[forward_fieldmethints->thisindex] = fmi;
760 nff = forward_fieldmethints;
761 forward_fieldmethints = forward_fieldmethints->next;
764 /* everything was ok */
770 /* loader_load_attribute_signature *********************************************
772 Signature_attribute {
773 u2 attribute_name_index;
778 *******************************************************************************/
780 #if defined(ENABLE_JAVASE)
781 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
791 /* check remaining bytecode */
793 if (!suck_check_classbuffer_size(cb, 4 + 2))
796 /* check attribute length */
798 attribute_length = suck_u4(cb);
800 if (attribute_length != 2) {
801 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
805 if (*signature != NULL) {
806 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
812 signature_index = suck_u2(cb);
814 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
819 #endif /* defined(ENABLE_JAVASE) */
822 /* load_field ******************************************************************
824 Load everything about a class field from the class file and fill a
825 'fieldinfo' structure. For static fields, space in the data segment
828 *******************************************************************************/
830 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
832 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
837 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
842 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
845 f->flags = suck_u2(cb);
847 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
852 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
856 f->parseddesc = NULL;
858 if (!descriptor_pool_add(descpool, u, NULL))
861 /* descriptor_pool_add accepts method descriptors, so we have to check */
862 /* against them here before the call of descriptor_to_basic_type below. */
863 if (u->text[0] == '(') {
864 exceptions_throw_classformaterror(c, "Method descriptor used for field");
868 #ifdef ENABLE_VERIFIER
871 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
872 exceptions_throw_classformaterror(c,
873 "Illegal Field name \"%s\"",
878 /* check flag consistency */
879 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
881 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
882 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
883 exceptions_throw_classformaterror(c,
884 "Illegal field modifiers: 0x%X",
889 if (c->flags & ACC_INTERFACE) {
890 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
891 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
892 f->flags & ACC_TRANSIENT) {
893 exceptions_throw_classformaterror(c,
894 "Illegal field modifiers: 0x%X",
900 #endif /* ENABLE_VERIFIER */
902 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
903 f->offset = 0; /* offset from start of object */
921 if (!(f->flags & ACC_STATIC))
922 c->flags |= ACC_CLASS_HAS_POINTERS;
935 /* read attributes */
936 if (!suck_check_classbuffer_size(cb, 2))
939 attrnum = suck_u2(cb);
940 for (i = 0; i < attrnum; i++) {
941 if (!suck_check_classbuffer_size(cb, 2))
944 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
947 if (u == utf_ConstantValue) {
948 if (!suck_check_classbuffer_size(cb, 4 + 2))
951 /* check attribute length */
953 if (suck_u4(cb) != 2) {
954 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
958 /* constant value attribute */
960 if (pindex != field_load_NOVALUE) {
961 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
965 /* index of value in constantpool */
967 pindex = suck_u2(cb);
969 /* initialize field with value from constantpool */
972 constant_integer *ci;
974 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
977 f->value.i = ci->value;
984 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
987 f->value.l = cl->value;
994 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
997 f->value.f = cf->value;
1002 constant_double *cd;
1004 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1007 f->value.d = cd->value;
1012 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1015 /* create javastring from compressed utf8-string */
1016 f->value.a = literalstring_new(u);
1020 log_text("Invalid Constant - Type");
1023 #if defined(ENABLE_JAVASE)
1024 else if (u == utf_Signature) {
1027 if (!loader_load_attribute_signature(cb, &(f->signature)))
1032 /* unknown attribute */
1034 if (!loader_skip_attribute_body(cb))
1039 /* everything was ok */
1045 /* loader_load_method **********************************************************
1047 Loads a method from the class file and fills an existing
1048 'methodinfo' structure. For native methods, the function pointer
1049 field is set to the real function pointer, for JavaVM methods a
1050 pointer to the compiler is used preliminarily.
1055 u2 descriptor_index;
1056 u2 attributes_count;
1057 attribute_info attributes[attribute_count];
1061 u2 attribute_name_index;
1062 u4 attribute_length;
1063 u1 info[attribute_length];
1066 LineNumberTable_attribute {
1067 u2 attribute_name_index;
1068 u4 attribute_length;
1069 u2 line_number_table_length;
1073 } line_number_table[line_number_table_length];
1076 *******************************************************************************/
1078 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1079 descriptor_pool *descpool)
1086 u2 descriptor_index;
1087 u2 attributes_count;
1088 u2 attribute_name_index;
1089 utf *attribute_name;
1090 u2 code_attributes_count;
1091 u2 code_attribute_name_index;
1092 utf *code_attribute_name;
1098 #if defined(ENABLE_THREADS)
1099 lock_init_object_lock(&m->header);
1102 #if defined(ENABLE_STATISTICS)
1104 count_all_methods++;
1107 /* all fields of m have been zeroed in load_class_from_classbuffer */
1111 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1116 m->flags = suck_u2(cb);
1120 name_index = suck_u2(cb);
1122 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1129 descriptor_index = suck_u2(cb);
1131 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1136 if (!descriptor_pool_add(descpool, u, &argcount))
1139 #ifdef ENABLE_VERIFIER
1141 if (!is_valid_name_utf(m->name)) {
1142 exceptions_throw_classformaterror(c, "Method with invalid name");
1146 if (m->name->text[0] == '<' &&
1147 m->name != utf_init && m->name != utf_clinit) {
1148 exceptions_throw_classformaterror(c, "Method with invalid special name");
1152 #endif /* ENABLE_VERIFIER */
1154 if (!(m->flags & ACC_STATIC))
1155 argcount++; /* count the 'this' argument */
1157 #ifdef ENABLE_VERIFIER
1159 if (argcount > 255) {
1160 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1164 /* check flag consistency */
1165 if (m->name != utf_clinit) {
1166 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1168 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1169 exceptions_throw_classformaterror(c,
1170 "Illegal method modifiers: 0x%X",
1175 if (m->flags & ACC_ABSTRACT) {
1176 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1177 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1178 exceptions_throw_classformaterror(c,
1179 "Illegal method modifiers: 0x%X",
1185 if (c->flags & ACC_INTERFACE) {
1186 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1187 exceptions_throw_classformaterror(c,
1188 "Illegal method modifiers: 0x%X",
1194 if (m->name == utf_init) {
1195 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1196 ACC_NATIVE | ACC_ABSTRACT)) {
1197 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1203 #endif /* ENABLE_VERIFIER */
1205 /* mark the method as monomorphic until further notice */
1207 m->flags |= ACC_METHOD_MONOMORPHIC;
1209 /* non-abstract methods have an implementation in this class */
1211 if (!(m->flags & ACC_ABSTRACT))
1212 m->flags |= ACC_METHOD_IMPLEMENTED;
1214 if (!suck_check_classbuffer_size(cb, 2))
1217 /* attributes count */
1219 attributes_count = suck_u2(cb);
1221 for (i = 0; i < attributes_count; i++) {
1222 if (!suck_check_classbuffer_size(cb, 2))
1225 /* attribute name index */
1227 attribute_name_index = suck_u2(cb);
1229 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1232 if (attribute_name == utf_Code) {
1234 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1235 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1240 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1244 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1248 m->maxstack = suck_u2(cb);
1249 m->maxlocals = suck_u2(cb);
1251 if (m->maxlocals < argcount) {
1252 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1256 if (!suck_check_classbuffer_size(cb, 4))
1259 m->jcodelength = suck_u4(cb);
1261 if (m->jcodelength == 0) {
1262 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1266 if (m->jcodelength > 65535) {
1267 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1271 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1274 m->jcode = MNEW(u1, m->jcodelength);
1275 suck_nbytes(m->jcode, cb, m->jcodelength);
1277 if (!suck_check_classbuffer_size(cb, 2))
1280 m->rawexceptiontablelength = suck_u2(cb);
1281 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1284 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1286 #if defined(ENABLE_STATISTICS)
1288 count_vmcode_len += m->jcodelength + 18;
1289 count_extable_len +=
1290 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1294 for (j = 0; j < m->rawexceptiontablelength; j++) {
1296 m->rawexceptiontable[j].startpc = suck_u2(cb);
1297 m->rawexceptiontable[j].endpc = suck_u2(cb);
1298 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1302 m->rawexceptiontable[j].catchtype.any = NULL;
1305 /* the classref is created later */
1306 if (!(m->rawexceptiontable[j].catchtype.any =
1307 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1312 if (!suck_check_classbuffer_size(cb, 2))
1315 /* code attributes count */
1317 code_attributes_count = suck_u2(cb);
1319 for (k = 0; k < code_attributes_count; k++) {
1320 if (!suck_check_classbuffer_size(cb, 2))
1323 /* code attribute name index */
1325 code_attribute_name_index = suck_u2(cb);
1327 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1330 /* check which code attribute */
1332 if (code_attribute_name == utf_LineNumberTable) {
1333 /* LineNumberTable */
1334 if (!suck_check_classbuffer_size(cb, 4 + 2))
1337 /* attribute length */
1341 /* line number table length */
1343 m->linenumbercount = suck_u2(cb);
1345 if (!suck_check_classbuffer_size(cb,
1346 (2 + 2) * m->linenumbercount))
1349 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1351 #if defined(ENABLE_STATISTICS)
1353 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1356 for (l = 0; l < m->linenumbercount; l++) {
1357 m->linenumbers[l].start_pc = suck_u2(cb);
1358 m->linenumbers[l].line_number = suck_u2(cb);
1361 #if defined(ENABLE_JAVASE)
1362 else if (code_attribute_name == utf_StackMapTable) {
1365 if (!stackmap_load_attribute_stackmaptable(cb, m))
1370 /* unknown code attribute */
1372 if (!loader_skip_attribute_body(cb))
1377 else if (attribute_name == utf_Exceptions) {
1380 if (m->thrownexceptions != NULL) {
1381 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1385 if (!suck_check_classbuffer_size(cb, 4 + 2))
1388 /* attribute length */
1392 m->thrownexceptionscount = suck_u2(cb);
1394 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1397 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1399 for (j = 0; j < m->thrownexceptionscount; j++) {
1400 /* the classref is created later */
1401 if (!((m->thrownexceptions)[j].any =
1402 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1406 #if defined(ENABLE_JAVASE)
1407 else if (attribute_name == utf_Signature) {
1410 if (!loader_load_attribute_signature(cb, &(m->signature)))
1415 /* unknown attribute */
1417 if (!loader_skip_attribute_body(cb))
1422 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1423 exceptions_throw_classformaterror(c, "Missing Code attribute");
1427 /* initialize the hit countdown field */
1429 #if defined(ENABLE_REPLACEMENT)
1430 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1433 /* everything was ok */
1439 /* load_class_from_sysloader ***************************************************
1441 Load the class with the given name using the system class loader
1444 name.............the classname
1447 the loaded class, or
1448 NULL if an exception has been thrown
1450 *******************************************************************************/
1452 classinfo *load_class_from_sysloader(utf *name)
1455 java_objectheader *cl;
1458 assert(class_java_lang_Object);
1459 assert(class_java_lang_ClassLoader);
1460 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1462 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1463 utf_getSystemClassLoader,
1464 utf_void__java_lang_ClassLoader,
1465 class_java_lang_Object,
1471 cl = vm_call_method(m, NULL);
1476 c = load_class_from_classloader(name, cl);
1482 /* load_class_from_classloader *************************************************
1484 Load the class with the given name using the given user-defined class loader.
1487 name.............the classname
1488 cl...............user-defined class loader
1491 the loaded class, or
1492 NULL if an exception has been thrown
1494 *******************************************************************************/
1496 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1498 java_objectheader *o;
1501 java_objectheader *string;
1502 #if defined(ENABLE_RT_TIMING)
1503 struct timespec time_start, time_lookup, time_prepare, time_java,
1507 RT_TIMING_GET_TIME(time_start);
1511 /* lookup if this class has already been loaded */
1513 c = classcache_lookup(cl, name);
1515 RT_TIMING_GET_TIME(time_lookup);
1516 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1521 /* if other class loader than bootstrap, call it */
1529 namelen = name->blength;
1531 /* handle array classes */
1532 if (text[0] == '[') {
1538 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1539 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1540 exceptions_throw_noclassdeffounderror(name);
1544 u = utf_new(text + 2, namelen - 3);
1546 if (!(comp = load_class_from_classloader(u, cl)))
1549 /* create the array class */
1551 c = class_array_of(comp, false);
1553 tmpc = classcache_store(cl, c, true);
1556 /* exception, free the loaded class */
1557 c->state &= ~CLASS_LOADING;
1564 /* load the component class */
1566 u = utf_new(text + 1, namelen - 1);
1568 if (!(comp = load_class_from_classloader(u, cl)))
1571 /* create the array class */
1573 c = class_array_of(comp, false);
1575 tmpc = classcache_store(cl, c, true);
1578 /* exception, free the loaded class */
1579 c->state &= ~CLASS_LOADING;
1586 /* primitive array classes are loaded by the bootstrap loader */
1588 c = load_class_bootstrap(name);
1594 assert(class_java_lang_Object);
1596 lc = class_resolveclassmethod(cl->vftbl->class,
1598 utf_java_lang_String__java_lang_Class,
1599 class_java_lang_Object,
1603 return false; /* exception */
1605 /* move return value into `o' and cast it afterwards to a classinfo* */
1607 string = javastring_new_slash_to_dot(name);
1609 RT_TIMING_GET_TIME(time_prepare);
1611 o = vm_call_method(lc, cl, string);
1613 RT_TIMING_GET_TIME(time_java);
1615 c = (classinfo *) o;
1618 /* Store this class in the loaded class cache. If another
1619 class with the same (initloader,name) pair has been
1620 stored earlier it will be returned by classcache_store
1621 In this case classcache_store may not free the class
1622 because it has already been exposed to Java code which
1623 may have kept references to that class. */
1625 tmpc = classcache_store(cl, c, false);
1628 /* exception, free the loaded class */
1629 c->state &= ~CLASS_LOADING;
1636 /* loadClass has thrown an exception. We must convert
1637 ClassNotFoundException into
1638 NoClassDefFoundException. */
1640 /* XXX Maybe we should have a flag that avoids this
1641 conversion for calling load_class_from_classloader from
1642 Class.forName. Currently we do a double conversion in
1645 classnotfoundexception_to_noclassdeffounderror();
1648 RT_TIMING_GET_TIME(time_cache);
1650 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1651 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1652 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1654 /* SUN compatible -verbose:class output */
1656 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1658 utf_display_printable_ascii_classname(name);
1662 #if defined(ENABLE_JVMTI)
1663 /* fire Class Load JVMTI event */
1664 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1671 c = load_class_bootstrap(name);
1677 /* load_class_bootstrap ********************************************************
1679 Load the class with the given name using the bootstrap class loader.
1682 name.............the classname
1685 loaded classinfo, or
1686 NULL if an exception has been thrown
1689 load_class_bootstrap is synchronized. It can be treated as an
1692 *******************************************************************************/
1694 classinfo *load_class_bootstrap(utf *name)
1699 #if defined(ENABLE_RT_TIMING)
1700 struct timespec time_start, time_lookup, time_array, time_suck,
1701 time_load, time_cache;
1704 RT_TIMING_GET_TIME(time_start);
1710 /* lookup if this class has already been loaded */
1712 if ((r = classcache_lookup(NULL, name))) {
1714 RT_TIMING_GET_TIME(time_lookup);
1715 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1720 RT_TIMING_GET_TIME(time_lookup);
1721 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1723 /* create the classinfo */
1725 c = class_create_classinfo(name);
1727 /* handle array classes */
1729 if (name->text[0] == '[') {
1730 c = load_newly_created_array(c, NULL);
1733 assert(c->state & CLASS_LOADED);
1735 RT_TIMING_GET_TIME(time_array);
1736 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1741 #if defined(ENABLE_STATISTICS)
1744 if (opt_getcompilingtime)
1745 compilingtime_stop();
1747 if (opt_getloadingtime)
1748 loadingtime_start();
1751 /* load classdata, throw exception on error */
1756 /* this normally means, the classpath was not set properly */
1758 if (name == utf_java_lang_Object)
1759 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1761 exceptions_throw_noclassdeffounderror(name);
1766 RT_TIMING_GET_TIME(time_suck);
1768 /* load the class from the buffer */
1770 r = load_class_from_classbuffer(cb);
1772 RT_TIMING_GET_TIME(time_load);
1775 /* the class could not be loaded, free the classinfo struct */
1780 /* Store this class in the loaded class cache this step also
1781 checks the loading constraints. If the class has been loaded
1782 before, the earlier loaded class is returned. */
1784 classinfo *res = classcache_store(NULL, c, true);
1794 RT_TIMING_GET_TIME(time_cache);
1796 /* SUN compatible -verbose:class output */
1798 if (opt_verboseclass && r) {
1800 utf_display_printable_ascii_classname(name);
1801 printf(" from %s]\n", cb->path);
1808 #if defined(ENABLE_STATISTICS)
1811 if (opt_getloadingtime)
1814 if (opt_getcompilingtime)
1815 compilingtime_start();
1818 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1819 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1820 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1821 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1827 /* load_class_from_classbuffer *************************************************
1829 Loads everything interesting about a class from the class file. The
1830 'classinfo' structure must have been allocated previously.
1832 The super class and the interfaces implemented by this class need
1833 not be loaded. The link is set later by the function 'class_link'.
1835 The loaded class is removed from the list 'unloadedclasses' and
1836 added to the list 'unlinkedclasses'.
1839 This function is NOT synchronized!
1841 *******************************************************************************/
1843 classinfo *load_class_from_classbuffer(classbuffer *cb)
1851 descriptor_pool *descpool;
1852 #if defined(ENABLE_STATISTICS)
1856 #if defined(ENABLE_RT_TIMING)
1857 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1858 time_setup, time_fields, time_methods, time_classrefs,
1859 time_descs, time_setrefs, time_parsefds, time_parsemds,
1860 time_parsecpool, time_verify, time_attrs;
1863 RT_TIMING_GET_TIME(time_start);
1865 /* get the classbuffer's class */
1869 /* the class is already loaded */
1871 if (c->state & CLASS_LOADED)
1874 #if defined(ENABLE_STATISTICS)
1876 count_class_loads++;
1879 #if !defined(NDEBUG)
1880 /* output for debugging purposes */
1883 log_message_class("Loading class: ", c);
1886 /* mark start of dump memory area */
1888 dumpsize = dump_size();
1890 /* class is currently loading */
1892 c->state |= CLASS_LOADING;
1894 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1895 goto return_exception;
1897 /* check signature */
1899 if (suck_u4(cb) != MAGIC) {
1900 exceptions_throw_classformaterror(c, "Bad magic number");
1902 goto return_exception;
1910 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1911 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1912 goto return_exception;
1915 RT_TIMING_GET_TIME(time_checks);
1917 /* create a new descriptor pool */
1919 descpool = descriptor_pool_new(c);
1921 RT_TIMING_GET_TIME(time_ndpool);
1923 /* load the constant pool */
1925 if (!load_constantpool(cb, descpool))
1926 goto return_exception;
1928 RT_TIMING_GET_TIME(time_cpool);
1932 if (!suck_check_classbuffer_size(cb, 2))
1933 goto return_exception;
1935 /* We OR the flags here, as we set already some flags in
1936 class_create_classinfo. */
1938 c->flags |= suck_u2(cb);
1940 /* check ACC flags consistency */
1942 if (c->flags & ACC_INTERFACE) {
1943 if (!(c->flags & ACC_ABSTRACT)) {
1944 /* We work around this because interfaces in JDK 1.1 are
1945 * not declared abstract. */
1947 c->flags |= ACC_ABSTRACT;
1950 if (c->flags & ACC_FINAL) {
1951 exceptions_throw_classformaterror(c,
1952 "Illegal class modifiers: 0x%X",
1954 goto return_exception;
1957 if (c->flags & ACC_SUPER) {
1958 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1962 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1963 exceptions_throw_classformaterror(c,
1964 "Illegal class modifiers: 0x%X",
1966 goto return_exception;
1969 if (!suck_check_classbuffer_size(cb, 2 + 2))
1970 goto return_exception;
1976 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1977 goto return_exception;
1979 if (c->name == utf_not_named_yet) {
1980 /* we finally have a name for this class */
1982 class_set_packagename(c);
1984 else if (name != c->name) {
1985 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1986 goto return_exception;
1989 /* retrieve superclass */
1991 c->super.any = NULL;
1993 if ((i = suck_u2(cb))) {
1994 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1995 goto return_exception;
1997 /* java.lang.Object may not have a super class. */
1999 if (c->name == utf_java_lang_Object) {
2000 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2001 goto return_exception;
2004 /* Interfaces must have java.lang.Object as super class. */
2006 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2007 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2008 goto return_exception;
2014 /* This is only allowed for java.lang.Object. */
2016 if (c->name != utf_java_lang_Object) {
2017 exceptions_throw_classformaterror(c, "Bad superclass index");
2018 goto return_exception;
2022 /* retrieve interfaces */
2024 if (!suck_check_classbuffer_size(cb, 2))
2025 goto return_exception;
2027 c->interfacescount = suck_u2(cb);
2029 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2030 goto return_exception;
2032 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2033 for (i = 0; i < c->interfacescount; i++) {
2034 /* the classrefs are created later */
2035 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2036 goto return_exception;
2039 RT_TIMING_GET_TIME(time_setup);
2042 if (!suck_check_classbuffer_size(cb, 2))
2043 goto return_exception;
2045 c->fieldscount = suck_u2(cb);
2046 #if defined(ENABLE_GC_CACAO)
2047 c->fields = MNEW(fieldinfo, c->fieldscount);
2048 MZERO(c->fields, fieldinfo, c->fieldscount);
2050 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2053 for (i = 0; i < c->fieldscount; i++) {
2054 if (!load_field(cb, &(c->fields[i]),descpool))
2055 goto return_exception;
2058 RT_TIMING_GET_TIME(time_fields);
2061 if (!suck_check_classbuffer_size(cb, 2))
2062 goto return_exception;
2064 c->methodscount = suck_u2(cb);
2065 c->methods = MNEW(methodinfo, c->methodscount);
2067 MZERO(c->methods, methodinfo, c->methodscount);
2069 for (i = 0; i < c->methodscount; i++) {
2070 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2071 goto return_exception;
2074 RT_TIMING_GET_TIME(time_methods);
2076 /* create the class reference table */
2079 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2081 RT_TIMING_GET_TIME(time_classrefs);
2083 /* allocate space for the parsed descriptors */
2085 descriptor_pool_alloc_parsed_descriptors(descpool);
2087 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2089 #if defined(ENABLE_STATISTICS)
2091 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2092 count_classref_len += classrefsize;
2093 count_parsed_desc_len += descsize;
2097 RT_TIMING_GET_TIME(time_descs);
2099 /* put the classrefs in the constant pool */
2100 for (i = 0; i < c->cpcount; i++) {
2101 if (c->cptags[i] == CONSTANT_Class) {
2102 utf *name = (utf *) c->cpinfos[i];
2103 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2107 /* set the super class reference */
2110 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2112 goto return_exception;
2115 /* set the super interfaces references */
2117 for (i = 0; i < c->interfacescount; i++) {
2118 c->interfaces[i].ref =
2119 descriptor_pool_lookup_classref(descpool,
2120 (utf *) c->interfaces[i].any);
2121 if (!c->interfaces[i].ref)
2122 goto return_exception;
2125 RT_TIMING_GET_TIME(time_setrefs);
2127 /* parse field descriptors */
2129 for (i = 0; i < c->fieldscount; i++) {
2130 c->fields[i].parseddesc =
2131 descriptor_pool_parse_field_descriptor(descpool,
2132 c->fields[i].descriptor);
2133 if (!c->fields[i].parseddesc)
2134 goto return_exception;
2137 RT_TIMING_GET_TIME(time_parsefds);
2139 /* parse method descriptors */
2141 for (i = 0; i < c->methodscount; i++) {
2142 methodinfo *m = &c->methods[i];
2144 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2145 m->flags, class_get_self_classref(m->class));
2147 goto return_exception;
2149 for (j = 0; j < m->rawexceptiontablelength; j++) {
2150 if (!m->rawexceptiontable[j].catchtype.any)
2152 if ((m->rawexceptiontable[j].catchtype.ref =
2153 descriptor_pool_lookup_classref(descpool,
2154 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2155 goto return_exception;
2158 for (j = 0; j < m->thrownexceptionscount; j++) {
2159 if (!m->thrownexceptions[j].any)
2161 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2162 (utf *) m->thrownexceptions[j].any)) == NULL)
2163 goto return_exception;
2167 RT_TIMING_GET_TIME(time_parsemds);
2169 /* parse the loaded descriptors */
2171 for (i = 0; i < c->cpcount; i++) {
2172 constant_FMIref *fmi;
2175 switch (c->cptags[i]) {
2176 case CONSTANT_Fieldref:
2177 fmi = (constant_FMIref *) c->cpinfos[i];
2178 fmi->parseddesc.fd =
2179 descriptor_pool_parse_field_descriptor(descpool,
2181 if (!fmi->parseddesc.fd)
2182 goto return_exception;
2183 index = fmi->p.index;
2185 (constant_classref *) class_getconstant(c, index,
2187 if (!fmi->p.classref)
2188 goto return_exception;
2190 case CONSTANT_Methodref:
2191 case CONSTANT_InterfaceMethodref:
2192 fmi = (constant_FMIref *) c->cpinfos[i];
2193 index = fmi->p.index;
2195 (constant_classref *) class_getconstant(c, index,
2197 if (!fmi->p.classref)
2198 goto return_exception;
2199 fmi->parseddesc.md =
2200 descriptor_pool_parse_method_descriptor(descpool,
2204 if (!fmi->parseddesc.md)
2205 goto return_exception;
2210 RT_TIMING_GET_TIME(time_parsecpool);
2212 #ifdef ENABLE_VERIFIER
2213 /* Check if all fields and methods can be uniquely
2214 * identified by (name,descriptor). */
2217 /* We use a hash table here to avoid making the
2218 * average case quadratic in # of methods, fields.
2220 static int shift = 0;
2222 u2 *next; /* for chaining colliding hash entries */
2228 /* Allocate hashtable */
2229 len = c->methodscount;
2230 if (len < c->fieldscount) len = c->fieldscount;
2232 hashtab = MNEW(u2,(hashlen + len));
2233 next = hashtab + hashlen;
2235 /* Determine bitshift (to get good hash values) */
2245 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2247 for (i = 0; i < c->fieldscount; ++i) {
2248 fieldinfo *fi = c->fields + i;
2250 /* It's ok if we lose bits here */
2251 index = ((((size_t) fi->name) +
2252 ((size_t) fi->descriptor)) >> shift) % hashlen;
2254 if ((old = hashtab[index])) {
2258 if (c->fields[old].name == fi->name &&
2259 c->fields[old].descriptor == fi->descriptor) {
2260 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2261 goto return_exception;
2263 } while ((old = next[old]));
2265 hashtab[index] = i + 1;
2269 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2271 for (i = 0; i < c->methodscount; ++i) {
2272 methodinfo *mi = c->methods + i;
2274 /* It's ok if we lose bits here */
2275 index = ((((size_t) mi->name) +
2276 ((size_t) mi->descriptor)) >> shift) % hashlen;
2280 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2281 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2285 if ((old = hashtab[index])) {
2289 if (c->methods[old].name == mi->name &&
2290 c->methods[old].descriptor == mi->descriptor) {
2291 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2292 goto return_exception;
2294 } while ((old = next[old]));
2296 hashtab[index] = i + 1;
2299 MFREE(hashtab, u2, (hashlen + len));
2301 #endif /* ENABLE_VERIFIER */
2303 RT_TIMING_GET_TIME(time_verify);
2305 #if defined(ENABLE_STATISTICS)
2307 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2308 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2309 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2313 /* load attribute structures */
2315 if (!class_load_attributes(cb))
2316 goto return_exception;
2318 /* Pre Java 1.5 version don't check this. This implementation is like
2319 Java 1.5 do it: for class file version 45.3 we don't check it, older
2320 versions are checked.
2323 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2324 /* check if all data has been read */
2325 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2327 if (classdata_left > 0) {
2328 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2329 goto return_exception;
2333 RT_TIMING_GET_TIME(time_attrs);
2335 /* release dump area */
2337 dump_release(dumpsize);
2339 /* revert loading state and class is loaded */
2341 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2343 #if defined(ENABLE_JVMTI)
2344 /* fire Class Prepare JVMTI event */
2347 jvmti_ClassLoadPrepare(true, c);
2350 #if !defined(NDEBUG)
2352 log_message_class("Loading done class: ", c);
2355 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2356 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2357 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2358 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2359 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2360 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2361 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2362 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2363 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2364 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2365 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2366 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2367 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2368 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2369 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2374 /* release dump area */
2376 dump_release(dumpsize);
2378 /* an exception has been thrown */
2384 /* load_newly_created_array ****************************************************
2386 Load a newly created array class.
2389 c....................the array class C has been loaded
2390 other classinfo......the array class was found in the class cache,
2392 NULL.................an exception has been thrown
2395 This is an internal function. Do not use it unless you know exactly
2398 Use one of the load_class_... functions for general array class loading.
2400 *******************************************************************************/
2402 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2404 classinfo *comp = NULL;
2406 methoddesc *clonedesc;
2407 constant_classref *classrefs;
2412 text = c->name->text;
2413 namelen = c->name->blength;
2415 /* Check array class name */
2417 if ((namelen < 2) || (text[0] != '[')) {
2418 exceptions_throw_noclassdeffounderror(c->name);
2422 /* Check the element type */
2426 /* c is an array of arrays. We have to create the component class. */
2428 u = utf_new(text + 1, namelen - 1);
2429 if (!(comp = load_class_from_classloader(u, loader)))
2432 assert(comp->state & CLASS_LOADED);
2438 /* the array's flags are that of the component class */
2439 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2440 c->classloader = comp->classloader;
2444 /* c is an array of objects. */
2446 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2447 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2448 exceptions_throw_noclassdeffounderror(c->name);
2452 u = utf_new(text + 2, namelen - 3);
2454 if (!(comp = load_class_from_classloader(u, loader)))
2457 assert(comp->state & CLASS_LOADED);
2463 /* the array's flags are that of the component class */
2464 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2465 c->classloader = comp->classloader;
2469 /* c is an array of a primitive type */
2471 /* check for cases like `[II' */
2473 exceptions_throw_noclassdeffounderror(c->name);
2477 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2478 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2479 c->classloader = NULL;
2482 assert(class_java_lang_Object);
2483 #if defined(ENABLE_JAVASE)
2484 assert(class_java_lang_Cloneable);
2485 assert(class_java_io_Serializable);
2488 /* setup the array class */
2490 c->super.cls = class_java_lang_Object;
2492 #if defined(ENABLE_JAVASE)
2493 c->interfacescount = 2;
2494 c->interfaces = MNEW(classref_or_classinfo, 2);
2499 tc = class_java_lang_Cloneable;
2500 assert(tc->state & CLASS_LOADED);
2501 list_add_first(&unlinkedclasses, tc);
2502 c->interfaces[0].cls = tc;
2504 tc = class_java_io_Serializable;
2505 assert(tc->state & CLASS_LOADED);
2506 list_add_first(&unlinkedclasses, tc);
2507 c->interfaces[1].cls = tc;
2510 c->interfaces[0].cls = class_java_lang_Cloneable;
2511 c->interfaces[1].cls = class_java_io_Serializable;
2513 #elif defined(ENABLE_JAVAME_CLDC1_1)
2514 c->interfacescount = 0;
2515 c->interfaces = NULL;
2517 #error unknow Java configuration
2520 c->methodscount = 1;
2521 c->methods = MNEW(methodinfo, c->methodscount);
2522 MZERO(c->methods, methodinfo, c->methodscount);
2524 classrefs = MNEW(constant_classref, 2);
2525 CLASSREF_INIT(classrefs[0], c, c->name);
2526 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2528 /* create descriptor for clone method */
2529 /* we need one paramslot which is reserved for the 'this' parameter */
2530 clonedesc = NEW(methoddesc);
2531 clonedesc->returntype.type = TYPE_ADR;
2532 clonedesc->returntype.classref = classrefs + 1;
2533 clonedesc->returntype.arraydim = 0;
2534 /* initialize params to "empty", add real params below in
2535 descriptor_params_from_paramtypes */
2536 clonedesc->paramcount = 0;
2537 clonedesc->paramslots = 0;
2538 clonedesc->paramtypes[0].classref = classrefs + 0;
2539 clonedesc->params = NULL;
2541 /* create methodinfo */
2544 MSET(clone, 0, methodinfo, 1);
2546 #if defined(ENABLE_THREADS)
2547 lock_init_object_lock(&clone->header);
2550 /* ATTENTION: if you delete the ACC_NATIVE below, set
2551 clone->maxlocals=1 (interpreter related) */
2553 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2554 clone->name = utf_clone;
2555 clone->descriptor = utf_void__java_lang_Object;
2556 clone->parseddesc = clonedesc;
2559 /* parse the descriptor to get the register allocation */
2561 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2564 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2566 /* XXX: field: length? */
2568 /* array classes are not loaded from class files */
2570 c->state |= CLASS_LOADED;
2571 c->parseddescs = (u1 *) clonedesc;
2572 c->parseddescsize = sizeof(methodinfo);
2573 c->classrefs = classrefs;
2574 c->classrefcount = 1;
2576 /* insert class into the loaded class cache */
2577 /* XXX free classinfo if NULL returned? */
2579 return classcache_store(loader, c, true);
2583 /* loader_close ****************************************************************
2585 Frees all resources.
2587 *******************************************************************************/
2589 void loader_close(void)
2596 * These are local overrides for various environment variables in Emacs.
2597 * Please do not remove this and leave it at the end of the file, where
2598 * Emacs will automagically detect them.
2599 * ---------------------------------------------------------------------
2602 * indent-tabs-mode: t
2606 * vim:noexpandtab:sw=4:ts=4: