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 7813 2007-04-25 19:20:13Z twisti $
38 #include "mm/memory.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/logging.h"
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/stringlocal.h"
50 #include "vm/jit_interface.h"
52 #if defined(ENABLE_JAVASE)
53 # include "vmcore/annotation.h"
54 # include "vmcore/stackmap.h"
57 #include "vmcore/classcache.h"
58 #include "vmcore/linker.h"
59 #include "vmcore/loader.h"
60 #include "vmcore/options.h"
61 #include "vmcore/rt-timing.h"
63 #if defined(ENABLE_STATISTICS)
64 # include "vmcore/statistics.h"
67 #include "vmcore/suck.h"
69 #if defined(ENABLE_ZLIB)
70 # include "vmcore/zip.h"
73 #if defined(ENABLE_JVMTI)
74 # include "native/jvmti/cacaodbg.h"
78 /* loader_init *****************************************************************
80 Initializes all lists and loads all classes required for the system
83 *******************************************************************************/
85 bool loader_init(void)
87 #if defined(ENABLE_THREADS)
88 list_classpath_entry *lce;
90 /* Initialize the monitor pointer for zip/jar file locking. */
92 for (lce = list_first(list_classpath_entries); lce != NULL;
93 lce = list_next(list_classpath_entries, lce))
94 if (lce->type == CLASSPATH_ARCHIVE)
95 LOCK_INIT_OBJECT_LOCK(lce);
98 /* load some important classes */
100 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
103 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
106 #if defined(ENABLE_JAVASE)
107 if (!(class_java_lang_Cloneable =
108 load_class_bootstrap(utf_java_lang_Cloneable)))
111 if (!(class_java_io_Serializable =
112 load_class_bootstrap(utf_java_io_Serializable)))
116 /* load classes for wrapping primitive types */
118 #if defined(ENABLE_JAVASE)
119 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
123 if (!(class_java_lang_Boolean =
124 load_class_bootstrap(utf_java_lang_Boolean)))
127 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
130 if (!(class_java_lang_Character =
131 load_class_bootstrap(utf_java_lang_Character)))
134 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
137 if (!(class_java_lang_Integer =
138 load_class_bootstrap(utf_java_lang_Integer)))
141 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
144 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
147 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
151 /* load some other important classes */
153 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
156 #if defined(ENABLE_JAVASE)
157 if (!(class_java_lang_ClassLoader =
158 load_class_bootstrap(utf_java_lang_ClassLoader)))
161 if (!(class_java_lang_SecurityManager =
162 load_class_bootstrap(utf_java_lang_SecurityManager)))
166 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
169 if (!(class_java_lang_Thread =
170 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
173 #if defined(ENABLE_JAVASE)
174 if (!(class_java_lang_ThreadGroup =
175 load_class_bootstrap(utf_java_lang_ThreadGroup)))
179 #if defined(WITH_CLASSPATH_GNU)
180 if (!(class_java_lang_VMSystem =
181 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
185 if (!(class_java_lang_VMThread =
186 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
191 /* some classes which may be used more often */
193 #if defined(ENABLE_JAVASE)
194 if (!(class_java_lang_StackTraceElement =
195 load_class_bootstrap(utf_java_lang_StackTraceElement)))
198 if (!(class_java_lang_reflect_Constructor =
199 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
202 if (!(class_java_lang_reflect_Field =
203 load_class_bootstrap(utf_java_lang_reflect_Field)))
206 if (!(class_java_lang_reflect_Method =
207 load_class_bootstrap(utf_java_lang_reflect_Method)))
210 if (!(class_java_security_PrivilegedAction =
211 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
214 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
217 if (!(arrayclass_java_lang_Object =
218 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
226 /* loader_load_all_classes *****************************************************
228 Loads all classes specified in the BOOTCLASSPATH.
230 *******************************************************************************/
232 void loader_load_all_classes(void)
234 list_classpath_entry *lce;
235 #if defined(ENABLE_ZLIB)
238 hashtable_zipfile_entry *htzfe;
242 for (lce = list_first(list_classpath_entries); lce != NULL;
243 lce = list_next(list_classpath_entries, lce)) {
244 #if defined(ENABLE_ZLIB)
245 if (lce->type == CLASSPATH_ARCHIVE) {
246 /* get the classes hashtable */
250 for (slot = 0; slot < ht->size; slot++) {
251 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
253 for (; htzfe; htzfe = htzfe->hashlink) {
256 /* skip all entries in META-INF and .properties,
259 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
260 strstr(u->text, ".properties") ||
261 strstr(u->text, ".png"))
264 /* load class from bootstrap classloader */
266 if (!load_class_bootstrap(u)) {
267 fprintf(stderr, "Error loading: ");
268 utf_fprint_printable_ascii_classname(stderr, u);
269 fprintf(stderr, "\n");
272 /* print out exception and cause */
274 exceptions_print_current_exception();
282 #if defined(ENABLE_ZLIB)
289 /* loader_skip_attribute_body **************************************************
291 Skips an attribute the attribute_name_index has already been read.
294 u2 attribute_name_index;
296 u1 info[attribute_length];
299 *******************************************************************************/
301 bool loader_skip_attribute_body(classbuffer *cb)
305 if (!suck_check_classbuffer_size(cb, 4))
308 attribute_length = suck_u4(cb);
310 if (!suck_check_classbuffer_size(cb, attribute_length))
313 suck_skip_nbytes(cb, attribute_length);
319 /* load_constantpool ***********************************************************
321 Loads the constantpool of a class, the entries are transformed into
322 a simpler format by resolving references (a detailed overview of
323 the compact structures can be found in global.h).
325 *******************************************************************************/
327 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
330 /* The following structures are used to save information which cannot be
331 processed during the first pass. After the complete constantpool has
332 been traversed the references can be resolved.
333 (only in specific order) */
335 /* CONSTANT_Class entries */
336 typedef struct forward_class {
337 struct forward_class *next;
342 /* CONSTANT_String */
343 typedef struct forward_string {
344 struct forward_string *next;
349 /* CONSTANT_NameAndType */
350 typedef struct forward_nameandtype {
351 struct forward_nameandtype *next;
355 } forward_nameandtype;
357 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
358 typedef struct forward_fieldmethint {
359 struct forward_fieldmethint *next;
363 u2 nameandtype_index;
364 } forward_fieldmethint;
370 forward_class *forward_classes = NULL;
371 forward_string *forward_strings = NULL;
372 forward_nameandtype *forward_nameandtypes = NULL;
373 forward_fieldmethint *forward_fieldmethints = NULL;
377 forward_nameandtype *nfn;
378 forward_fieldmethint *nff;
386 /* number of entries in the constant_pool table plus one */
387 if (!suck_check_classbuffer_size(cb, 2))
390 cpcount = c->cpcount = suck_u2(cb);
392 /* allocate memory */
393 cptags = c->cptags = MNEW(u1, cpcount);
394 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
397 exceptions_throw_classformaterror(c, "Illegal constant pool size");
401 #if defined(ENABLE_STATISTICS)
403 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
406 /* initialize constantpool */
407 for (idx = 0; idx < cpcount; idx++) {
408 cptags[idx] = CONSTANT_UNUSED;
413 /******* first pass *******/
414 /* entries which cannot be resolved now are written into
415 temporary structures and traversed again later */
418 while (idx < cpcount) {
421 /* get constant type */
422 if (!suck_check_classbuffer_size(cb, 1))
429 nfc = DNEW(forward_class);
431 nfc->next = forward_classes;
432 forward_classes = nfc;
434 nfc->thisindex = idx;
435 /* reference to CONSTANT_NameAndType */
436 if (!suck_check_classbuffer_size(cb, 2))
439 nfc->name_index = suck_u2(cb);
444 case CONSTANT_String:
445 nfs = DNEW(forward_string);
447 nfs->next = forward_strings;
448 forward_strings = nfs;
450 nfs->thisindex = idx;
452 /* reference to CONSTANT_Utf8_info with string characters */
453 if (!suck_check_classbuffer_size(cb, 2))
456 nfs->string_index = suck_u2(cb);
461 case CONSTANT_NameAndType:
462 nfn = DNEW(forward_nameandtype);
464 nfn->next = forward_nameandtypes;
465 forward_nameandtypes = nfn;
467 nfn->thisindex = idx;
469 if (!suck_check_classbuffer_size(cb, 2 + 2))
472 /* reference to CONSTANT_Utf8_info containing simple name */
473 nfn->name_index = suck_u2(cb);
475 /* reference to CONSTANT_Utf8_info containing field or method
477 nfn->sig_index = suck_u2(cb);
482 case CONSTANT_Fieldref:
483 case CONSTANT_Methodref:
484 case CONSTANT_InterfaceMethodref:
485 nff = DNEW(forward_fieldmethint);
487 nff->next = forward_fieldmethints;
488 forward_fieldmethints = nff;
490 nff->thisindex = idx;
494 if (!suck_check_classbuffer_size(cb, 2 + 2))
497 /* class or interface type that contains the declaration of the
499 nff->class_index = suck_u2(cb);
501 /* name and descriptor of the field or method */
502 nff->nameandtype_index = suck_u2(cb);
507 case CONSTANT_Integer: {
508 constant_integer *ci = NEW(constant_integer);
510 #if defined(ENABLE_STATISTICS)
512 count_const_pool_len += sizeof(constant_integer);
515 if (!suck_check_classbuffer_size(cb, 4))
518 ci->value = suck_s4(cb);
519 cptags[idx] = CONSTANT_Integer;
526 case CONSTANT_Float: {
527 constant_float *cf = NEW(constant_float);
529 #if defined(ENABLE_STATISTICS)
531 count_const_pool_len += sizeof(constant_float);
534 if (!suck_check_classbuffer_size(cb, 4))
537 cf->value = suck_float(cb);
538 cptags[idx] = CONSTANT_Float;
545 case CONSTANT_Long: {
546 constant_long *cl = NEW(constant_long);
548 #if defined(ENABLE_STATISTICS)
550 count_const_pool_len += sizeof(constant_long);
553 if (!suck_check_classbuffer_size(cb, 8))
556 cl->value = suck_s8(cb);
557 cptags[idx] = CONSTANT_Long;
561 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
567 case CONSTANT_Double: {
568 constant_double *cd = NEW(constant_double);
570 #if defined(ENABLE_STATISTICS)
572 count_const_pool_len += sizeof(constant_double);
575 if (!suck_check_classbuffer_size(cb, 8))
578 cd->value = suck_double(cb);
579 cptags[idx] = CONSTANT_Double;
583 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
589 case CONSTANT_Utf8: {
592 /* number of bytes in the bytes array (not string-length) */
593 if (!suck_check_classbuffer_size(cb, 2))
596 length = suck_u2(cb);
597 cptags[idx] = CONSTANT_Utf8;
599 /* validate the string */
600 if (!suck_check_classbuffer_size(cb, length))
603 #ifdef ENABLE_VERIFIER
605 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
607 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
610 #endif /* ENABLE_VERIFIER */
611 /* insert utf-string into the utf-symboltable */
612 cpinfos[idx] = utf_new((char *) cb->pos, length);
614 /* skip bytes of the string (buffer size check above) */
615 suck_skip_nbytes(cb, length);
621 exceptions_throw_classformaterror(c, "Illegal constant pool type");
627 /* resolve entries in temporary structures */
629 while (forward_classes) {
631 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
635 #ifdef ENABLE_VERIFIER
636 if (opt_verify && !is_valid_name_utf(name)) {
637 exceptions_throw_classformaterror(c, "Class reference with invalid name");
640 #endif /* ENABLE_VERIFIER */
642 /* add all class references to the descriptor_pool */
644 if (!descriptor_pool_add_class(descpool, name))
647 cptags[forward_classes->thisindex] = CONSTANT_Class;
652 if (!(tc = load_class_bootstrap(name)))
655 /* link the class later, because we cannot link the class currently
657 list_add_first(&unlinkedclasses, tc);
660 /* the classref is created later */
661 cpinfos[forward_classes->thisindex] = name;
663 nfc = forward_classes;
664 forward_classes = forward_classes->next;
667 while (forward_strings) {
669 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
673 /* resolve utf-string */
674 cptags[forward_strings->thisindex] = CONSTANT_String;
675 cpinfos[forward_strings->thisindex] = text;
677 nfs = forward_strings;
678 forward_strings = forward_strings->next;
681 while (forward_nameandtypes) {
682 constant_nameandtype *cn = NEW(constant_nameandtype);
684 #if defined(ENABLE_STATISTICS)
686 count_const_pool_len += sizeof(constant_nameandtype);
689 /* resolve simple name and descriptor */
690 cn->name = class_getconstant(c,
691 forward_nameandtypes->name_index,
696 cn->descriptor = class_getconstant(c,
697 forward_nameandtypes->sig_index,
702 #ifdef ENABLE_VERIFIER
705 if (!is_valid_name_utf(cn->name)) {
706 exceptions_throw_classformaterror(c,
707 "Illegal Field name \"%s\"",
713 /* disallow referencing <clinit> among others */
714 if (cn->name->text[0] == '<' && cn->name != utf_init) {
715 exceptions_throw_classformaterror(c, "Illegal reference to special method");
719 #endif /* ENABLE_VERIFIER */
721 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
722 cpinfos[forward_nameandtypes->thisindex] = cn;
724 nfn = forward_nameandtypes;
725 forward_nameandtypes = forward_nameandtypes->next;
728 while (forward_fieldmethints) {
729 constant_nameandtype *nat;
730 constant_FMIref *fmi = NEW(constant_FMIref);
732 #if defined(ENABLE_STATISTICS)
734 count_const_pool_len += sizeof(constant_FMIref);
736 /* resolve simple name and descriptor */
738 nat = class_getconstant(c,
739 forward_fieldmethints->nameandtype_index,
740 CONSTANT_NameAndType);
744 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
746 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
749 /* the classref is created later */
751 fmi->p.index = forward_fieldmethints->class_index;
752 fmi->name = nat->name;
753 fmi->descriptor = nat->descriptor;
755 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
756 cpinfos[forward_fieldmethints->thisindex] = fmi;
758 nff = forward_fieldmethints;
759 forward_fieldmethints = forward_fieldmethints->next;
762 /* everything was ok */
768 /* loader_load_attribute_signature *********************************************
770 Signature_attribute {
771 u2 attribute_name_index;
776 *******************************************************************************/
778 #if defined(ENABLE_JAVASE)
779 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
789 /* check remaining bytecode */
791 if (!suck_check_classbuffer_size(cb, 4 + 2))
794 /* check attribute length */
796 attribute_length = suck_u4(cb);
798 if (attribute_length != 2) {
799 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
803 if (*signature != NULL) {
804 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
810 signature_index = suck_u2(cb);
812 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
817 #endif /* defined(ENABLE_JAVASE) */
820 /* load_field ******************************************************************
822 Load everything about a class field from the class file and fill a
823 'fieldinfo' structure. For static fields, space in the data segment
826 *******************************************************************************/
828 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
830 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
835 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
840 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
843 f->flags = suck_u2(cb);
845 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
850 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
854 f->parseddesc = NULL;
856 if (!descriptor_pool_add(descpool, u, NULL))
859 /* descriptor_pool_add accepts method descriptors, so we have to check */
860 /* against them here before the call of descriptor_to_basic_type below. */
861 if (u->text[0] == '(') {
862 exceptions_throw_classformaterror(c, "Method descriptor used for field");
866 #ifdef ENABLE_VERIFIER
869 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
870 exceptions_throw_classformaterror(c,
871 "Illegal Field name \"%s\"",
876 /* check flag consistency */
877 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
879 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
880 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
881 exceptions_throw_classformaterror(c,
882 "Illegal field modifiers: 0x%X",
887 if (c->flags & ACC_INTERFACE) {
888 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
889 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
890 f->flags & ACC_TRANSIENT) {
891 exceptions_throw_classformaterror(c,
892 "Illegal field modifiers: 0x%X",
898 #endif /* ENABLE_VERIFIER */
900 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
901 f->offset = 0; /* offset from start of object */
919 if (!(f->flags & ACC_STATIC))
920 c->flags |= ACC_CLASS_HAS_POINTERS;
933 /* read attributes */
934 if (!suck_check_classbuffer_size(cb, 2))
937 attrnum = suck_u2(cb);
938 for (i = 0; i < attrnum; i++) {
939 if (!suck_check_classbuffer_size(cb, 2))
942 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
945 if (u == utf_ConstantValue) {
946 if (!suck_check_classbuffer_size(cb, 4 + 2))
949 /* check attribute length */
951 if (suck_u4(cb) != 2) {
952 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
956 /* constant value attribute */
958 if (pindex != field_load_NOVALUE) {
959 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
963 /* index of value in constantpool */
965 pindex = suck_u2(cb);
967 /* initialize field with value from constantpool */
970 constant_integer *ci;
972 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
975 f->value.i = ci->value;
982 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
985 f->value.l = cl->value;
992 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
995 f->value.f = cf->value;
1000 constant_double *cd;
1002 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1005 f->value.d = cd->value;
1010 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1013 /* create javastring from compressed utf8-string */
1014 f->value.a = literalstring_new(u);
1018 log_text("Invalid Constant - Type");
1021 #if defined(ENABLE_JAVASE)
1022 else if (u == utf_Signature) {
1025 if (!loader_load_attribute_signature(cb, &(f->signature)))
1030 /* unknown attribute */
1032 if (!loader_skip_attribute_body(cb))
1037 /* everything was ok */
1043 /* loader_load_method **********************************************************
1045 Loads a method from the class file and fills an existing
1046 'methodinfo' structure. For native methods, the function pointer
1047 field is set to the real function pointer, for JavaVM methods a
1048 pointer to the compiler is used preliminarily.
1053 u2 descriptor_index;
1054 u2 attributes_count;
1055 attribute_info attributes[attribute_count];
1059 u2 attribute_name_index;
1060 u4 attribute_length;
1061 u1 info[attribute_length];
1064 LineNumberTable_attribute {
1065 u2 attribute_name_index;
1066 u4 attribute_length;
1067 u2 line_number_table_length;
1071 } line_number_table[line_number_table_length];
1074 *******************************************************************************/
1076 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1077 descriptor_pool *descpool)
1084 u2 descriptor_index;
1085 u2 attributes_count;
1086 u2 attribute_name_index;
1087 utf *attribute_name;
1088 u2 code_attributes_count;
1089 u2 code_attribute_name_index;
1090 utf *code_attribute_name;
1096 #if defined(ENABLE_THREADS)
1097 lock_init_object_lock(&m->header);
1100 #if defined(ENABLE_STATISTICS)
1102 count_all_methods++;
1105 /* all fields of m have been zeroed in load_class_from_classbuffer */
1109 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1114 m->flags = suck_u2(cb);
1118 name_index = suck_u2(cb);
1120 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1127 descriptor_index = suck_u2(cb);
1129 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1134 if (!descriptor_pool_add(descpool, u, &argcount))
1137 #ifdef ENABLE_VERIFIER
1139 if (!is_valid_name_utf(m->name)) {
1140 exceptions_throw_classformaterror(c, "Method with invalid name");
1144 if (m->name->text[0] == '<' &&
1145 m->name != utf_init && m->name != utf_clinit) {
1146 exceptions_throw_classformaterror(c, "Method with invalid special name");
1150 #endif /* ENABLE_VERIFIER */
1152 if (!(m->flags & ACC_STATIC))
1153 argcount++; /* count the 'this' argument */
1155 #ifdef ENABLE_VERIFIER
1157 if (argcount > 255) {
1158 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1162 /* check flag consistency */
1163 if (m->name != utf_clinit) {
1164 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1166 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1167 exceptions_throw_classformaterror(c,
1168 "Illegal method modifiers: 0x%X",
1173 if (m->flags & ACC_ABSTRACT) {
1174 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1175 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1176 exceptions_throw_classformaterror(c,
1177 "Illegal method modifiers: 0x%X",
1183 if (c->flags & ACC_INTERFACE) {
1184 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1185 exceptions_throw_classformaterror(c,
1186 "Illegal method modifiers: 0x%X",
1192 if (m->name == utf_init) {
1193 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1194 ACC_NATIVE | ACC_ABSTRACT)) {
1195 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1201 #endif /* ENABLE_VERIFIER */
1203 /* mark the method as monomorphic until further notice */
1205 m->flags |= ACC_METHOD_MONOMORPHIC;
1207 /* non-abstract methods have an implementation in this class */
1209 if (!(m->flags & ACC_ABSTRACT))
1210 m->flags |= ACC_METHOD_IMPLEMENTED;
1212 if (!suck_check_classbuffer_size(cb, 2))
1215 /* attributes count */
1217 attributes_count = suck_u2(cb);
1219 for (i = 0; i < attributes_count; i++) {
1220 if (!suck_check_classbuffer_size(cb, 2))
1223 /* attribute name index */
1225 attribute_name_index = suck_u2(cb);
1227 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1230 if (attribute_name == utf_Code) {
1232 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1233 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1238 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1242 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1246 m->maxstack = suck_u2(cb);
1247 m->maxlocals = suck_u2(cb);
1249 if (m->maxlocals < argcount) {
1250 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1254 if (!suck_check_classbuffer_size(cb, 4))
1257 m->jcodelength = suck_u4(cb);
1259 if (m->jcodelength == 0) {
1260 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1264 if (m->jcodelength > 65535) {
1265 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1269 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1272 m->jcode = MNEW(u1, m->jcodelength);
1273 suck_nbytes(m->jcode, cb, m->jcodelength);
1275 if (!suck_check_classbuffer_size(cb, 2))
1278 m->rawexceptiontablelength = suck_u2(cb);
1279 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1282 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1284 #if defined(ENABLE_STATISTICS)
1286 count_vmcode_len += m->jcodelength + 18;
1287 count_extable_len +=
1288 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1292 for (j = 0; j < m->rawexceptiontablelength; j++) {
1294 m->rawexceptiontable[j].startpc = suck_u2(cb);
1295 m->rawexceptiontable[j].endpc = suck_u2(cb);
1296 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1300 m->rawexceptiontable[j].catchtype.any = NULL;
1303 /* the classref is created later */
1304 if (!(m->rawexceptiontable[j].catchtype.any =
1305 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1310 if (!suck_check_classbuffer_size(cb, 2))
1313 /* code attributes count */
1315 code_attributes_count = suck_u2(cb);
1317 for (k = 0; k < code_attributes_count; k++) {
1318 if (!suck_check_classbuffer_size(cb, 2))
1321 /* code attribute name index */
1323 code_attribute_name_index = suck_u2(cb);
1325 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1328 /* check which code attribute */
1330 if (code_attribute_name == utf_LineNumberTable) {
1331 /* LineNumberTable */
1332 if (!suck_check_classbuffer_size(cb, 4 + 2))
1335 /* attribute length */
1339 /* line number table length */
1341 m->linenumbercount = suck_u2(cb);
1343 if (!suck_check_classbuffer_size(cb,
1344 (2 + 2) * m->linenumbercount))
1347 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1349 #if defined(ENABLE_STATISTICS)
1351 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1354 for (l = 0; l < m->linenumbercount; l++) {
1355 m->linenumbers[l].start_pc = suck_u2(cb);
1356 m->linenumbers[l].line_number = suck_u2(cb);
1359 #if defined(ENABLE_JAVASE)
1360 else if (code_attribute_name == utf_StackMapTable) {
1363 if (!stackmap_load_attribute_stackmaptable(cb, m))
1368 /* unknown code attribute */
1370 if (!loader_skip_attribute_body(cb))
1375 else if (attribute_name == utf_Exceptions) {
1378 if (m->thrownexceptions != NULL) {
1379 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1383 if (!suck_check_classbuffer_size(cb, 4 + 2))
1386 /* attribute length */
1390 m->thrownexceptionscount = suck_u2(cb);
1392 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1395 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1397 for (j = 0; j < m->thrownexceptionscount; j++) {
1398 /* the classref is created later */
1399 if (!((m->thrownexceptions)[j].any =
1400 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1404 #if defined(ENABLE_JAVASE)
1405 else if (attribute_name == utf_Signature) {
1408 if (!loader_load_attribute_signature(cb, &(m->signature)))
1413 /* unknown attribute */
1415 if (!loader_skip_attribute_body(cb))
1420 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1421 exceptions_throw_classformaterror(c, "Missing Code attribute");
1425 /* initialize the hit countdown field */
1427 #if defined(ENABLE_REPLACEMENT)
1428 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1431 /* everything was ok */
1437 /* load_class_from_sysloader ***************************************************
1439 Load the class with the given name using the system class loader
1442 name.............the classname
1445 the loaded class, or
1446 NULL if an exception has been thrown
1448 *******************************************************************************/
1450 classinfo *load_class_from_sysloader(utf *name)
1453 java_objectheader *cl;
1456 assert(class_java_lang_Object);
1457 assert(class_java_lang_ClassLoader);
1458 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1460 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1461 utf_getSystemClassLoader,
1462 utf_void__java_lang_ClassLoader,
1463 class_java_lang_Object,
1469 cl = vm_call_method(m, NULL);
1474 c = load_class_from_classloader(name, cl);
1480 /* load_class_from_classloader *************************************************
1482 Load the class with the given name using the given user-defined class loader.
1485 name.............the classname
1486 cl...............user-defined class loader
1489 the loaded class, or
1490 NULL if an exception has been thrown
1492 *******************************************************************************/
1494 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1496 java_objectheader *o;
1499 java_objectheader *string;
1500 #if defined(ENABLE_RT_TIMING)
1501 struct timespec time_start, time_lookup, time_prepare, time_java,
1505 RT_TIMING_GET_TIME(time_start);
1509 /* lookup if this class has already been loaded */
1511 c = classcache_lookup(cl, name);
1513 RT_TIMING_GET_TIME(time_lookup);
1514 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1519 /* if other class loader than bootstrap, call it */
1527 namelen = name->blength;
1529 /* handle array classes */
1530 if (text[0] == '[') {
1536 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1537 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1538 exceptions_throw_noclassdeffounderror(name);
1542 u = utf_new(text + 2, namelen - 3);
1544 if (!(comp = load_class_from_classloader(u, cl)))
1547 /* create the array class */
1549 c = class_array_of(comp, false);
1551 tmpc = classcache_store(cl, c, true);
1554 /* exception, free the loaded class */
1555 c->state &= ~CLASS_LOADING;
1562 /* load the component class */
1564 u = utf_new(text + 1, namelen - 1);
1566 if (!(comp = load_class_from_classloader(u, cl)))
1569 /* create the array class */
1571 c = class_array_of(comp, false);
1573 tmpc = classcache_store(cl, c, true);
1576 /* exception, free the loaded class */
1577 c->state &= ~CLASS_LOADING;
1584 /* primitive array classes are loaded by the bootstrap loader */
1586 c = load_class_bootstrap(name);
1592 assert(class_java_lang_Object);
1594 lc = class_resolveclassmethod(cl->vftbl->class,
1596 utf_java_lang_String__java_lang_Class,
1597 class_java_lang_Object,
1601 return false; /* exception */
1603 /* move return value into `o' and cast it afterwards to a classinfo* */
1605 string = javastring_new_slash_to_dot(name);
1607 RT_TIMING_GET_TIME(time_prepare);
1609 o = vm_call_method(lc, cl, string);
1611 RT_TIMING_GET_TIME(time_java);
1613 c = (classinfo *) o;
1616 /* Store this class in the loaded class cache. If another
1617 class with the same (initloader,name) pair has been
1618 stored earlier it will be returned by classcache_store
1619 In this case classcache_store may not free the class
1620 because it has already been exposed to Java code which
1621 may have kept references to that class. */
1623 tmpc = classcache_store(cl, c, false);
1626 /* exception, free the loaded class */
1627 c->state &= ~CLASS_LOADING;
1634 /* loadClass has thrown an exception. We must convert
1635 ClassNotFoundException into
1636 NoClassDefFoundException. */
1638 /* XXX Maybe we should have a flag that avoids this
1639 conversion for calling load_class_from_classloader from
1640 Class.forName. Currently we do a double conversion in
1643 classnotfoundexception_to_noclassdeffounderror();
1646 RT_TIMING_GET_TIME(time_cache);
1648 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1649 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1650 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1652 /* SUN compatible -verbose:class output */
1654 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1656 utf_display_printable_ascii_classname(name);
1660 #if defined(ENABLE_JVMTI)
1661 /* fire Class Load JVMTI event */
1662 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1669 c = load_class_bootstrap(name);
1675 /* load_class_bootstrap ********************************************************
1677 Load the class with the given name using the bootstrap class loader.
1680 name.............the classname
1683 loaded classinfo, or
1684 NULL if an exception has been thrown
1687 load_class_bootstrap is synchronized. It can be treated as an
1690 *******************************************************************************/
1692 classinfo *load_class_bootstrap(utf *name)
1697 #if defined(ENABLE_RT_TIMING)
1698 struct timespec time_start, time_lookup, time_array, time_suck,
1699 time_load, time_cache;
1702 RT_TIMING_GET_TIME(time_start);
1708 /* lookup if this class has already been loaded */
1710 if ((r = classcache_lookup(NULL, name))) {
1712 RT_TIMING_GET_TIME(time_lookup);
1713 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1718 RT_TIMING_GET_TIME(time_lookup);
1719 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1721 /* create the classinfo */
1723 c = class_create_classinfo(name);
1725 /* handle array classes */
1727 if (name->text[0] == '[') {
1728 c = load_newly_created_array(c, NULL);
1731 assert(c->state & CLASS_LOADED);
1733 RT_TIMING_GET_TIME(time_array);
1734 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1739 #if defined(ENABLE_STATISTICS)
1742 if (opt_getcompilingtime)
1743 compilingtime_stop();
1745 if (opt_getloadingtime)
1746 loadingtime_start();
1749 /* load classdata, throw exception on error */
1754 /* this normally means, the classpath was not set properly */
1756 if (name == utf_java_lang_Object)
1757 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1759 exceptions_throw_noclassdeffounderror(name);
1764 RT_TIMING_GET_TIME(time_suck);
1766 /* load the class from the buffer */
1768 r = load_class_from_classbuffer(cb);
1770 RT_TIMING_GET_TIME(time_load);
1773 /* the class could not be loaded, free the classinfo struct */
1778 /* Store this class in the loaded class cache this step also
1779 checks the loading constraints. If the class has been loaded
1780 before, the earlier loaded class is returned. */
1782 classinfo *res = classcache_store(NULL, c, true);
1792 RT_TIMING_GET_TIME(time_cache);
1794 /* SUN compatible -verbose:class output */
1796 if (opt_verboseclass && r) {
1798 utf_display_printable_ascii_classname(name);
1799 printf(" from %s]\n", cb->path);
1806 #if defined(ENABLE_STATISTICS)
1809 if (opt_getloadingtime)
1812 if (opt_getcompilingtime)
1813 compilingtime_start();
1816 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1817 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1818 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1819 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1825 /* load_class_from_classbuffer *************************************************
1827 Loads everything interesting about a class from the class file. The
1828 'classinfo' structure must have been allocated previously.
1830 The super class and the interfaces implemented by this class need
1831 not be loaded. The link is set later by the function 'class_link'.
1833 The loaded class is removed from the list 'unloadedclasses' and
1834 added to the list 'unlinkedclasses'.
1837 This function is NOT synchronized!
1839 *******************************************************************************/
1841 classinfo *load_class_from_classbuffer(classbuffer *cb)
1849 descriptor_pool *descpool;
1850 #if defined(ENABLE_STATISTICS)
1854 #if defined(ENABLE_RT_TIMING)
1855 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1856 time_setup, time_fields, time_methods, time_classrefs,
1857 time_descs, time_setrefs, time_parsefds, time_parsemds,
1858 time_parsecpool, time_verify, time_attrs;
1861 RT_TIMING_GET_TIME(time_start);
1863 /* get the classbuffer's class */
1867 /* the class is already loaded */
1869 if (c->state & CLASS_LOADED)
1872 #if defined(ENABLE_STATISTICS)
1874 count_class_loads++;
1877 #if !defined(NDEBUG)
1878 /* output for debugging purposes */
1881 log_message_class("Loading class: ", c);
1884 /* mark start of dump memory area */
1886 dumpsize = dump_size();
1888 /* class is currently loading */
1890 c->state |= CLASS_LOADING;
1892 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1893 goto return_exception;
1895 /* check signature */
1897 if (suck_u4(cb) != MAGIC) {
1898 exceptions_throw_classformaterror(c, "Bad magic number");
1900 goto return_exception;
1908 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1909 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1910 goto return_exception;
1913 RT_TIMING_GET_TIME(time_checks);
1915 /* create a new descriptor pool */
1917 descpool = descriptor_pool_new(c);
1919 RT_TIMING_GET_TIME(time_ndpool);
1921 /* load the constant pool */
1923 if (!load_constantpool(cb, descpool))
1924 goto return_exception;
1926 RT_TIMING_GET_TIME(time_cpool);
1930 if (!suck_check_classbuffer_size(cb, 2))
1931 goto return_exception;
1933 /* We OR the flags here, as we set already some flags in
1934 class_create_classinfo. */
1936 c->flags |= suck_u2(cb);
1938 /* check ACC flags consistency */
1940 if (c->flags & ACC_INTERFACE) {
1941 if (!(c->flags & ACC_ABSTRACT)) {
1942 /* We work around this because interfaces in JDK 1.1 are
1943 * not declared abstract. */
1945 c->flags |= ACC_ABSTRACT;
1948 if (c->flags & ACC_FINAL) {
1949 exceptions_throw_classformaterror(c,
1950 "Illegal class modifiers: 0x%X",
1952 goto return_exception;
1955 if (c->flags & ACC_SUPER) {
1956 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1960 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1961 exceptions_throw_classformaterror(c,
1962 "Illegal class modifiers: 0x%X",
1964 goto return_exception;
1967 if (!suck_check_classbuffer_size(cb, 2 + 2))
1968 goto return_exception;
1974 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1975 goto return_exception;
1977 if (c->name == utf_not_named_yet) {
1978 /* we finally have a name for this class */
1980 class_set_packagename(c);
1982 else if (name != c->name) {
1983 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1984 goto return_exception;
1987 /* retrieve superclass */
1989 c->super.any = NULL;
1991 if ((i = suck_u2(cb))) {
1992 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1993 goto return_exception;
1995 /* java.lang.Object may not have a super class. */
1997 if (c->name == utf_java_lang_Object) {
1998 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1999 goto return_exception;
2002 /* Interfaces must have java.lang.Object as super class. */
2004 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2005 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2006 goto return_exception;
2012 /* This is only allowed for java.lang.Object. */
2014 if (c->name != utf_java_lang_Object) {
2015 exceptions_throw_classformaterror(c, "Bad superclass index");
2016 goto return_exception;
2020 /* retrieve interfaces */
2022 if (!suck_check_classbuffer_size(cb, 2))
2023 goto return_exception;
2025 c->interfacescount = suck_u2(cb);
2027 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2028 goto return_exception;
2030 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2031 for (i = 0; i < c->interfacescount; i++) {
2032 /* the classrefs are created later */
2033 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2034 goto return_exception;
2037 RT_TIMING_GET_TIME(time_setup);
2040 if (!suck_check_classbuffer_size(cb, 2))
2041 goto return_exception;
2043 c->fieldscount = suck_u2(cb);
2044 #if defined(ENABLE_GC_CACAO)
2045 c->fields = MNEW(fieldinfo, c->fieldscount);
2046 MZERO(c->fields, fieldinfo, c->fieldscount);
2048 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2051 for (i = 0; i < c->fieldscount; i++) {
2052 if (!load_field(cb, &(c->fields[i]),descpool))
2053 goto return_exception;
2056 RT_TIMING_GET_TIME(time_fields);
2059 if (!suck_check_classbuffer_size(cb, 2))
2060 goto return_exception;
2062 c->methodscount = suck_u2(cb);
2063 c->methods = MNEW(methodinfo, c->methodscount);
2065 MZERO(c->methods, methodinfo, c->methodscount);
2067 for (i = 0; i < c->methodscount; i++) {
2068 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2069 goto return_exception;
2072 RT_TIMING_GET_TIME(time_methods);
2074 /* create the class reference table */
2077 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2079 RT_TIMING_GET_TIME(time_classrefs);
2081 /* allocate space for the parsed descriptors */
2083 descriptor_pool_alloc_parsed_descriptors(descpool);
2085 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2087 #if defined(ENABLE_STATISTICS)
2089 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2090 count_classref_len += classrefsize;
2091 count_parsed_desc_len += descsize;
2095 RT_TIMING_GET_TIME(time_descs);
2097 /* put the classrefs in the constant pool */
2098 for (i = 0; i < c->cpcount; i++) {
2099 if (c->cptags[i] == CONSTANT_Class) {
2100 utf *name = (utf *) c->cpinfos[i];
2101 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2105 /* set the super class reference */
2108 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2110 goto return_exception;
2113 /* set the super interfaces references */
2115 for (i = 0; i < c->interfacescount; i++) {
2116 c->interfaces[i].ref =
2117 descriptor_pool_lookup_classref(descpool,
2118 (utf *) c->interfaces[i].any);
2119 if (!c->interfaces[i].ref)
2120 goto return_exception;
2123 RT_TIMING_GET_TIME(time_setrefs);
2125 /* parse field descriptors */
2127 for (i = 0; i < c->fieldscount; i++) {
2128 c->fields[i].parseddesc =
2129 descriptor_pool_parse_field_descriptor(descpool,
2130 c->fields[i].descriptor);
2131 if (!c->fields[i].parseddesc)
2132 goto return_exception;
2135 RT_TIMING_GET_TIME(time_parsefds);
2137 /* parse method descriptors */
2139 for (i = 0; i < c->methodscount; i++) {
2140 methodinfo *m = &c->methods[i];
2142 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2143 m->flags, class_get_self_classref(m->class));
2145 goto return_exception;
2147 for (j = 0; j < m->rawexceptiontablelength; j++) {
2148 if (!m->rawexceptiontable[j].catchtype.any)
2150 if ((m->rawexceptiontable[j].catchtype.ref =
2151 descriptor_pool_lookup_classref(descpool,
2152 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2153 goto return_exception;
2156 for (j = 0; j < m->thrownexceptionscount; j++) {
2157 if (!m->thrownexceptions[j].any)
2159 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2160 (utf *) m->thrownexceptions[j].any)) == NULL)
2161 goto return_exception;
2165 RT_TIMING_GET_TIME(time_parsemds);
2167 /* parse the loaded descriptors */
2169 for (i = 0; i < c->cpcount; i++) {
2170 constant_FMIref *fmi;
2173 switch (c->cptags[i]) {
2174 case CONSTANT_Fieldref:
2175 fmi = (constant_FMIref *) c->cpinfos[i];
2176 fmi->parseddesc.fd =
2177 descriptor_pool_parse_field_descriptor(descpool,
2179 if (!fmi->parseddesc.fd)
2180 goto return_exception;
2181 index = fmi->p.index;
2183 (constant_classref *) class_getconstant(c, index,
2185 if (!fmi->p.classref)
2186 goto return_exception;
2188 case CONSTANT_Methodref:
2189 case CONSTANT_InterfaceMethodref:
2190 fmi = (constant_FMIref *) c->cpinfos[i];
2191 index = fmi->p.index;
2193 (constant_classref *) class_getconstant(c, index,
2195 if (!fmi->p.classref)
2196 goto return_exception;
2197 fmi->parseddesc.md =
2198 descriptor_pool_parse_method_descriptor(descpool,
2202 if (!fmi->parseddesc.md)
2203 goto return_exception;
2208 RT_TIMING_GET_TIME(time_parsecpool);
2210 #ifdef ENABLE_VERIFIER
2211 /* Check if all fields and methods can be uniquely
2212 * identified by (name,descriptor). */
2215 /* We use a hash table here to avoid making the
2216 * average case quadratic in # of methods, fields.
2218 static int shift = 0;
2220 u2 *next; /* for chaining colliding hash entries */
2226 /* Allocate hashtable */
2227 len = c->methodscount;
2228 if (len < c->fieldscount) len = c->fieldscount;
2230 hashtab = MNEW(u2,(hashlen + len));
2231 next = hashtab + hashlen;
2233 /* Determine bitshift (to get good hash values) */
2243 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2245 for (i = 0; i < c->fieldscount; ++i) {
2246 fieldinfo *fi = c->fields + i;
2248 /* It's ok if we lose bits here */
2249 index = ((((size_t) fi->name) +
2250 ((size_t) fi->descriptor)) >> shift) % hashlen;
2252 if ((old = hashtab[index])) {
2256 if (c->fields[old].name == fi->name &&
2257 c->fields[old].descriptor == fi->descriptor) {
2258 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2259 goto return_exception;
2261 } while ((old = next[old]));
2263 hashtab[index] = i + 1;
2267 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2269 for (i = 0; i < c->methodscount; ++i) {
2270 methodinfo *mi = c->methods + i;
2272 /* It's ok if we lose bits here */
2273 index = ((((size_t) mi->name) +
2274 ((size_t) mi->descriptor)) >> shift) % hashlen;
2278 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2279 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2283 if ((old = hashtab[index])) {
2287 if (c->methods[old].name == mi->name &&
2288 c->methods[old].descriptor == mi->descriptor) {
2289 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2290 goto return_exception;
2292 } while ((old = next[old]));
2294 hashtab[index] = i + 1;
2297 MFREE(hashtab, u2, (hashlen + len));
2299 #endif /* ENABLE_VERIFIER */
2301 RT_TIMING_GET_TIME(time_verify);
2303 #if defined(ENABLE_STATISTICS)
2305 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2306 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2307 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2311 /* load attribute structures */
2313 if (!class_load_attributes(cb))
2314 goto return_exception;
2316 /* Pre Java 1.5 version don't check this. This implementation is like
2317 Java 1.5 do it: for class file version 45.3 we don't check it, older
2318 versions are checked.
2321 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2322 /* check if all data has been read */
2323 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2325 if (classdata_left > 0) {
2326 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2327 goto return_exception;
2331 RT_TIMING_GET_TIME(time_attrs);
2333 /* release dump area */
2335 dump_release(dumpsize);
2337 /* revert loading state and class is loaded */
2339 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2341 #if defined(ENABLE_JVMTI)
2342 /* fire Class Prepare JVMTI event */
2345 jvmti_ClassLoadPrepare(true, c);
2348 #if !defined(NDEBUG)
2350 log_message_class("Loading done class: ", c);
2353 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2354 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2355 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2356 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2357 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2358 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2359 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2360 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2361 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2362 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2363 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2364 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2365 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2366 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2367 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2372 /* release dump area */
2374 dump_release(dumpsize);
2376 /* an exception has been thrown */
2382 /* load_newly_created_array ****************************************************
2384 Load a newly created array class.
2387 c....................the array class C has been loaded
2388 other classinfo......the array class was found in the class cache,
2390 NULL.................an exception has been thrown
2393 This is an internal function. Do not use it unless you know exactly
2396 Use one of the load_class_... functions for general array class loading.
2398 *******************************************************************************/
2400 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2402 classinfo *comp = NULL;
2404 methoddesc *clonedesc;
2405 constant_classref *classrefs;
2410 text = c->name->text;
2411 namelen = c->name->blength;
2413 /* Check array class name */
2415 if ((namelen < 2) || (text[0] != '[')) {
2416 exceptions_throw_noclassdeffounderror(c->name);
2420 /* Check the element type */
2424 /* c is an array of arrays. We have to create the component class. */
2426 u = utf_new(text + 1, namelen - 1);
2427 if (!(comp = load_class_from_classloader(u, loader)))
2430 assert(comp->state & CLASS_LOADED);
2436 /* the array's flags are that of the component class */
2437 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2438 c->classloader = comp->classloader;
2442 /* c is an array of objects. */
2444 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2445 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2446 exceptions_throw_noclassdeffounderror(c->name);
2450 u = utf_new(text + 2, namelen - 3);
2452 if (!(comp = load_class_from_classloader(u, loader)))
2455 assert(comp->state & CLASS_LOADED);
2461 /* the array's flags are that of the component class */
2462 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2463 c->classloader = comp->classloader;
2467 /* c is an array of a primitive type */
2469 /* check for cases like `[II' */
2471 exceptions_throw_noclassdeffounderror(c->name);
2475 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2476 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2477 c->classloader = NULL;
2480 assert(class_java_lang_Object);
2481 #if defined(ENABLE_JAVASE)
2482 assert(class_java_lang_Cloneable);
2483 assert(class_java_io_Serializable);
2486 /* setup the array class */
2488 c->super.cls = class_java_lang_Object;
2490 #if defined(ENABLE_JAVASE)
2491 c->interfacescount = 2;
2492 c->interfaces = MNEW(classref_or_classinfo, 2);
2497 tc = class_java_lang_Cloneable;
2498 assert(tc->state & CLASS_LOADED);
2499 list_add_first(&unlinkedclasses, tc);
2500 c->interfaces[0].cls = tc;
2502 tc = class_java_io_Serializable;
2503 assert(tc->state & CLASS_LOADED);
2504 list_add_first(&unlinkedclasses, tc);
2505 c->interfaces[1].cls = tc;
2508 c->interfaces[0].cls = class_java_lang_Cloneable;
2509 c->interfaces[1].cls = class_java_io_Serializable;
2511 #elif defined(ENABLE_JAVAME_CLDC1_1)
2512 c->interfacescount = 0;
2513 c->interfaces = NULL;
2515 #error unknow Java configuration
2518 c->methodscount = 1;
2519 c->methods = MNEW(methodinfo, c->methodscount);
2520 MZERO(c->methods, methodinfo, c->methodscount);
2522 classrefs = MNEW(constant_classref, 2);
2523 CLASSREF_INIT(classrefs[0], c, c->name);
2524 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2526 /* create descriptor for clone method */
2527 /* we need one paramslot which is reserved for the 'this' parameter */
2528 clonedesc = NEW(methoddesc);
2529 clonedesc->returntype.type = TYPE_ADR;
2530 clonedesc->returntype.classref = classrefs + 1;
2531 clonedesc->returntype.arraydim = 0;
2532 /* initialize params to "empty", add real params below in
2533 descriptor_params_from_paramtypes */
2534 clonedesc->paramcount = 0;
2535 clonedesc->paramslots = 0;
2536 clonedesc->paramtypes[0].classref = classrefs + 0;
2537 clonedesc->params = NULL;
2539 /* create methodinfo */
2542 MSET(clone, 0, methodinfo, 1);
2544 #if defined(ENABLE_THREADS)
2545 lock_init_object_lock(&clone->header);
2548 /* ATTENTION: if you delete the ACC_NATIVE below, set
2549 clone->maxlocals=1 (interpreter related) */
2551 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2552 clone->name = utf_clone;
2553 clone->descriptor = utf_void__java_lang_Object;
2554 clone->parseddesc = clonedesc;
2557 /* parse the descriptor to get the register allocation */
2559 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2562 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2564 /* XXX: field: length? */
2566 /* array classes are not loaded from class files */
2568 c->state |= CLASS_LOADED;
2569 c->parseddescs = (u1 *) clonedesc;
2570 c->parseddescsize = sizeof(methodinfo);
2571 c->classrefs = classrefs;
2572 c->classrefcount = 1;
2574 /* insert class into the loaded class cache */
2575 /* XXX free classinfo if NULL returned? */
2577 return classcache_store(loader, c, true);
2581 /* loader_close ****************************************************************
2583 Frees all resources.
2585 *******************************************************************************/
2587 void loader_close(void)
2594 * These are local overrides for various environment variables in Emacs.
2595 * Please do not remove this and leave it at the end of the file, where
2596 * Emacs will automagically detect them.
2597 * ---------------------------------------------------------------------
2600 * indent-tabs-mode: t
2604 * vim:noexpandtab:sw=4:ts=4: