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 7918 2007-05-20 20:42:18Z michi $
38 #include "mm/memory.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit_interface.h"
53 #if defined(ENABLE_JAVASE)
54 # include "vmcore/annotation.h"
55 # include "vmcore/stackmap.h"
58 #include "vmcore/classcache.h"
59 #include "vmcore/linker.h"
60 #include "vmcore/loader.h"
61 #include "vmcore/options.h"
62 #include "vmcore/rt-timing.h"
64 #if defined(ENABLE_STATISTICS)
65 # include "vmcore/statistics.h"
68 #include "vmcore/suck.h"
70 #if defined(ENABLE_ZLIB)
71 # include "vmcore/zip.h"
74 #if defined(ENABLE_JVMTI)
75 # include "native/jvmti/cacaodbg.h"
79 /* global variables ***********************************************************/
81 hashtable *hashtable_classloader;
84 /* loader_init *****************************************************************
86 Initializes all lists and loads all classes required for the system
89 *******************************************************************************/
91 bool loader_init(void)
93 #if defined(ENABLE_THREADS)
94 list_classpath_entry *lce;
96 /* Initialize the monitor pointer for zip/jar file locking. */
98 for (lce = list_first(list_classpath_entries); lce != NULL;
99 lce = list_next(list_classpath_entries, lce))
100 if (lce->type == CLASSPATH_ARCHIVE)
101 LOCK_INIT_OBJECT_LOCK(lce);
104 /* initialize classloader hashtable, 10 entries should be enough */
106 hashtable_classloader = NEW(hashtable);
107 hashtable_create(hashtable_classloader, 10);
109 /* load some important classes */
111 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
114 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
117 #if defined(ENABLE_JAVASE)
118 if (!(class_java_lang_Cloneable =
119 load_class_bootstrap(utf_java_lang_Cloneable)))
122 if (!(class_java_io_Serializable =
123 load_class_bootstrap(utf_java_io_Serializable)))
127 /* load classes for wrapping primitive types */
129 #if defined(ENABLE_JAVASE)
130 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
134 if (!(class_java_lang_Boolean =
135 load_class_bootstrap(utf_java_lang_Boolean)))
138 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
141 if (!(class_java_lang_Character =
142 load_class_bootstrap(utf_java_lang_Character)))
145 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
148 if (!(class_java_lang_Integer =
149 load_class_bootstrap(utf_java_lang_Integer)))
152 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
155 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
158 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
162 /* load some other important classes */
164 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
167 #if defined(ENABLE_JAVASE)
168 if (!(class_java_lang_ClassLoader =
169 load_class_bootstrap(utf_java_lang_ClassLoader)))
172 if (!(class_java_lang_SecurityManager =
173 load_class_bootstrap(utf_java_lang_SecurityManager)))
177 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
180 if (!(class_java_lang_Thread =
181 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
184 #if defined(ENABLE_JAVASE)
185 if (!(class_java_lang_ThreadGroup =
186 load_class_bootstrap(utf_java_lang_ThreadGroup)))
190 #if defined(WITH_CLASSPATH_GNU)
191 if (!(class_java_lang_VMSystem =
192 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
196 if (!(class_java_lang_VMThread =
197 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
202 /* some classes which may be used more often */
204 #if defined(ENABLE_JAVASE)
205 if (!(class_java_lang_StackTraceElement =
206 load_class_bootstrap(utf_java_lang_StackTraceElement)))
209 if (!(class_java_lang_reflect_Constructor =
210 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
213 if (!(class_java_lang_reflect_Field =
214 load_class_bootstrap(utf_java_lang_reflect_Field)))
217 if (!(class_java_lang_reflect_Method =
218 load_class_bootstrap(utf_java_lang_reflect_Method)))
221 if (!(class_java_security_PrivilegedAction =
222 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
225 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
228 if (!(arrayclass_java_lang_Object =
229 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
237 /* loader_hashtable_classloader_add ********************************************
239 Adds an entry to the classloader hashtable.
241 REMEMBER: Also use this to register native loaders!
243 *******************************************************************************/
245 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
247 hashtable_classloader_entry *cle;
254 LOCK_MONITOR_ENTER(hashtable_classloader->header);
256 /* key for entry is the hashcode of the classloader;
257 aligned to 16-byte boundaries */
259 #if defined(ENABLE_GC_CACAO)
260 key = heap_get_hashcode(cl) >> 4;
262 key = ((u4) (ptrint) cl) >> 4;
265 slot = key & (hashtable_classloader->size - 1);
266 cle = hashtable_classloader->ptr[slot];
268 /* search hashchain for existing entry */
269 /* XXX no GC collection is allowed here, make this a critical section */
272 if (cle->object == cl)
278 /* if no classloader was found, we create a new entry here */
281 cle = NEW(hashtable_classloader_entry);
285 /* insert entry into hashtable */
287 cle->hashlink = hashtable_classloader->ptr[slot];
288 hashtable_classloader->ptr[slot] = cle;
290 /* update number of entries */
292 hashtable_classloader->entries++;
296 LOCK_MONITOR_EXIT(hashtable_classloader->header);
302 /* loader_hashtable_classloader_find *******************************************
304 Find an entry in the classloader hashtable.
306 *******************************************************************************/
308 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
310 hashtable_classloader_entry *cle;
317 /* key for entry is the hashcode of the classloader;
318 aligned to 16-byte boundaries */
320 #if defined(ENABLE_GC_CACAO)
321 key = heap_get_hashcode(cl) >> 4;
323 key = ((u4) (ptrint) cl) >> 4;
326 slot = key & (hashtable_classloader->size - 1);
327 cle = hashtable_classloader->ptr[slot];
329 /* search hashchain for existing entry */
330 /* XXX no GC collection is allowed here, make this a critical section */
333 if (cle->object == cl)
343 /* loader_load_all_classes *****************************************************
345 Loads all classes specified in the BOOTCLASSPATH.
347 *******************************************************************************/
349 void loader_load_all_classes(void)
351 list_classpath_entry *lce;
352 #if defined(ENABLE_ZLIB)
355 hashtable_zipfile_entry *htzfe;
359 for (lce = list_first(list_classpath_entries); lce != NULL;
360 lce = list_next(list_classpath_entries, lce)) {
361 #if defined(ENABLE_ZLIB)
362 if (lce->type == CLASSPATH_ARCHIVE) {
363 /* get the classes hashtable */
367 for (slot = 0; slot < ht->size; slot++) {
368 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
370 for (; htzfe; htzfe = htzfe->hashlink) {
373 /* skip all entries in META-INF and .properties,
376 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
377 strstr(u->text, ".properties") ||
378 strstr(u->text, ".png"))
381 /* load class from bootstrap classloader */
383 if (!load_class_bootstrap(u)) {
384 fprintf(stderr, "Error loading: ");
385 utf_fprint_printable_ascii_classname(stderr, u);
386 fprintf(stderr, "\n");
389 /* print out exception and cause */
391 exceptions_print_current_exception();
399 #if defined(ENABLE_ZLIB)
406 /* loader_skip_attribute_body **************************************************
408 Skips an attribute the attribute_name_index has already been read.
411 u2 attribute_name_index;
413 u1 info[attribute_length];
416 *******************************************************************************/
418 bool loader_skip_attribute_body(classbuffer *cb)
422 if (!suck_check_classbuffer_size(cb, 4))
425 attribute_length = suck_u4(cb);
427 if (!suck_check_classbuffer_size(cb, attribute_length))
430 suck_skip_nbytes(cb, attribute_length);
436 /* load_constantpool ***********************************************************
438 Loads the constantpool of a class, the entries are transformed into
439 a simpler format by resolving references (a detailed overview of
440 the compact structures can be found in global.h).
442 *******************************************************************************/
444 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
447 /* The following structures are used to save information which cannot be
448 processed during the first pass. After the complete constantpool has
449 been traversed the references can be resolved.
450 (only in specific order) */
452 /* CONSTANT_Class entries */
453 typedef struct forward_class {
454 struct forward_class *next;
459 /* CONSTANT_String */
460 typedef struct forward_string {
461 struct forward_string *next;
466 /* CONSTANT_NameAndType */
467 typedef struct forward_nameandtype {
468 struct forward_nameandtype *next;
472 } forward_nameandtype;
474 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
475 typedef struct forward_fieldmethint {
476 struct forward_fieldmethint *next;
480 u2 nameandtype_index;
481 } forward_fieldmethint;
487 forward_class *forward_classes = NULL;
488 forward_string *forward_strings = NULL;
489 forward_nameandtype *forward_nameandtypes = NULL;
490 forward_fieldmethint *forward_fieldmethints = NULL;
494 forward_nameandtype *nfn;
495 forward_fieldmethint *nff;
503 /* number of entries in the constant_pool table plus one */
504 if (!suck_check_classbuffer_size(cb, 2))
507 cpcount = c->cpcount = suck_u2(cb);
509 /* allocate memory */
510 cptags = c->cptags = MNEW(u1, cpcount);
511 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
514 exceptions_throw_classformaterror(c, "Illegal constant pool size");
518 #if defined(ENABLE_STATISTICS)
520 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
523 /* initialize constantpool */
524 for (idx = 0; idx < cpcount; idx++) {
525 cptags[idx] = CONSTANT_UNUSED;
530 /******* first pass *******/
531 /* entries which cannot be resolved now are written into
532 temporary structures and traversed again later */
535 while (idx < cpcount) {
538 /* get constant type */
539 if (!suck_check_classbuffer_size(cb, 1))
546 nfc = DNEW(forward_class);
548 nfc->next = forward_classes;
549 forward_classes = nfc;
551 nfc->thisindex = idx;
552 /* reference to CONSTANT_NameAndType */
553 if (!suck_check_classbuffer_size(cb, 2))
556 nfc->name_index = suck_u2(cb);
561 case CONSTANT_String:
562 nfs = DNEW(forward_string);
564 nfs->next = forward_strings;
565 forward_strings = nfs;
567 nfs->thisindex = idx;
569 /* reference to CONSTANT_Utf8_info with string characters */
570 if (!suck_check_classbuffer_size(cb, 2))
573 nfs->string_index = suck_u2(cb);
578 case CONSTANT_NameAndType:
579 nfn = DNEW(forward_nameandtype);
581 nfn->next = forward_nameandtypes;
582 forward_nameandtypes = nfn;
584 nfn->thisindex = idx;
586 if (!suck_check_classbuffer_size(cb, 2 + 2))
589 /* reference to CONSTANT_Utf8_info containing simple name */
590 nfn->name_index = suck_u2(cb);
592 /* reference to CONSTANT_Utf8_info containing field or method
594 nfn->sig_index = suck_u2(cb);
599 case CONSTANT_Fieldref:
600 case CONSTANT_Methodref:
601 case CONSTANT_InterfaceMethodref:
602 nff = DNEW(forward_fieldmethint);
604 nff->next = forward_fieldmethints;
605 forward_fieldmethints = nff;
607 nff->thisindex = idx;
611 if (!suck_check_classbuffer_size(cb, 2 + 2))
614 /* class or interface type that contains the declaration of the
616 nff->class_index = suck_u2(cb);
618 /* name and descriptor of the field or method */
619 nff->nameandtype_index = suck_u2(cb);
624 case CONSTANT_Integer: {
625 constant_integer *ci = NEW(constant_integer);
627 #if defined(ENABLE_STATISTICS)
629 count_const_pool_len += sizeof(constant_integer);
632 if (!suck_check_classbuffer_size(cb, 4))
635 ci->value = suck_s4(cb);
636 cptags[idx] = CONSTANT_Integer;
643 case CONSTANT_Float: {
644 constant_float *cf = NEW(constant_float);
646 #if defined(ENABLE_STATISTICS)
648 count_const_pool_len += sizeof(constant_float);
651 if (!suck_check_classbuffer_size(cb, 4))
654 cf->value = suck_float(cb);
655 cptags[idx] = CONSTANT_Float;
662 case CONSTANT_Long: {
663 constant_long *cl = NEW(constant_long);
665 #if defined(ENABLE_STATISTICS)
667 count_const_pool_len += sizeof(constant_long);
670 if (!suck_check_classbuffer_size(cb, 8))
673 cl->value = suck_s8(cb);
674 cptags[idx] = CONSTANT_Long;
678 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
684 case CONSTANT_Double: {
685 constant_double *cd = NEW(constant_double);
687 #if defined(ENABLE_STATISTICS)
689 count_const_pool_len += sizeof(constant_double);
692 if (!suck_check_classbuffer_size(cb, 8))
695 cd->value = suck_double(cb);
696 cptags[idx] = CONSTANT_Double;
700 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
706 case CONSTANT_Utf8: {
709 /* number of bytes in the bytes array (not string-length) */
710 if (!suck_check_classbuffer_size(cb, 2))
713 length = suck_u2(cb);
714 cptags[idx] = CONSTANT_Utf8;
716 /* validate the string */
717 if (!suck_check_classbuffer_size(cb, length))
720 #ifdef ENABLE_VERIFIER
722 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
724 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
727 #endif /* ENABLE_VERIFIER */
728 /* insert utf-string into the utf-symboltable */
729 cpinfos[idx] = utf_new((char *) cb->pos, length);
731 /* skip bytes of the string (buffer size check above) */
732 suck_skip_nbytes(cb, length);
738 exceptions_throw_classformaterror(c, "Illegal constant pool type");
744 /* resolve entries in temporary structures */
746 while (forward_classes) {
748 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
752 #ifdef ENABLE_VERIFIER
753 if (opt_verify && !is_valid_name_utf(name)) {
754 exceptions_throw_classformaterror(c, "Class reference with invalid name");
757 #endif /* ENABLE_VERIFIER */
759 /* add all class references to the descriptor_pool */
761 if (!descriptor_pool_add_class(descpool, name))
764 cptags[forward_classes->thisindex] = CONSTANT_Class;
769 if (!(tc = load_class_bootstrap(name)))
772 /* link the class later, because we cannot link the class currently
774 list_add_first(&unlinkedclasses, tc);
777 /* the classref is created later */
778 cpinfos[forward_classes->thisindex] = name;
780 nfc = forward_classes;
781 forward_classes = forward_classes->next;
784 while (forward_strings) {
786 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
790 /* resolve utf-string */
791 cptags[forward_strings->thisindex] = CONSTANT_String;
792 cpinfos[forward_strings->thisindex] = text;
794 nfs = forward_strings;
795 forward_strings = forward_strings->next;
798 while (forward_nameandtypes) {
799 constant_nameandtype *cn = NEW(constant_nameandtype);
801 #if defined(ENABLE_STATISTICS)
803 count_const_pool_len += sizeof(constant_nameandtype);
806 /* resolve simple name and descriptor */
807 cn->name = class_getconstant(c,
808 forward_nameandtypes->name_index,
813 cn->descriptor = class_getconstant(c,
814 forward_nameandtypes->sig_index,
819 #ifdef ENABLE_VERIFIER
822 if (!is_valid_name_utf(cn->name)) {
823 exceptions_throw_classformaterror(c,
824 "Illegal Field name \"%s\"",
830 /* disallow referencing <clinit> among others */
831 if (cn->name->text[0] == '<' && cn->name != utf_init) {
832 exceptions_throw_classformaterror(c, "Illegal reference to special method");
836 #endif /* ENABLE_VERIFIER */
838 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
839 cpinfos[forward_nameandtypes->thisindex] = cn;
841 nfn = forward_nameandtypes;
842 forward_nameandtypes = forward_nameandtypes->next;
845 while (forward_fieldmethints) {
846 constant_nameandtype *nat;
847 constant_FMIref *fmi = NEW(constant_FMIref);
849 #if defined(ENABLE_STATISTICS)
851 count_const_pool_len += sizeof(constant_FMIref);
853 /* resolve simple name and descriptor */
855 nat = class_getconstant(c,
856 forward_fieldmethints->nameandtype_index,
857 CONSTANT_NameAndType);
861 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
863 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
866 /* the classref is created later */
868 fmi->p.index = forward_fieldmethints->class_index;
869 fmi->name = nat->name;
870 fmi->descriptor = nat->descriptor;
872 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
873 cpinfos[forward_fieldmethints->thisindex] = fmi;
875 nff = forward_fieldmethints;
876 forward_fieldmethints = forward_fieldmethints->next;
879 /* everything was ok */
885 /* loader_load_attribute_signature *********************************************
887 Signature_attribute {
888 u2 attribute_name_index;
893 *******************************************************************************/
895 #if defined(ENABLE_JAVASE)
896 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
906 /* check remaining bytecode */
908 if (!suck_check_classbuffer_size(cb, 4 + 2))
911 /* check attribute length */
913 attribute_length = suck_u4(cb);
915 if (attribute_length != 2) {
916 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
920 if (*signature != NULL) {
921 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
927 signature_index = suck_u2(cb);
929 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
934 #endif /* defined(ENABLE_JAVASE) */
937 /* load_field ******************************************************************
939 Load everything about a class field from the class file and fill a
940 'fieldinfo' structure. For static fields, space in the data segment
943 *******************************************************************************/
945 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
947 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
952 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
957 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
960 f->flags = suck_u2(cb);
962 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
967 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
971 f->parseddesc = NULL;
973 if (!descriptor_pool_add(descpool, u, NULL))
976 /* descriptor_pool_add accepts method descriptors, so we have to check */
977 /* against them here before the call of descriptor_to_basic_type below. */
978 if (u->text[0] == '(') {
979 exceptions_throw_classformaterror(c, "Method descriptor used for field");
983 #ifdef ENABLE_VERIFIER
986 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
987 exceptions_throw_classformaterror(c,
988 "Illegal Field name \"%s\"",
993 /* check flag consistency */
994 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
996 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
997 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
998 exceptions_throw_classformaterror(c,
999 "Illegal field modifiers: 0x%X",
1004 if (c->flags & ACC_INTERFACE) {
1005 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1006 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1007 f->flags & ACC_TRANSIENT) {
1008 exceptions_throw_classformaterror(c,
1009 "Illegal field modifiers: 0x%X",
1015 #endif /* ENABLE_VERIFIER */
1017 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1018 f->offset = 0; /* offset from start of object */
1036 if (!(f->flags & ACC_STATIC))
1037 c->flags |= ACC_CLASS_HAS_POINTERS;
1045 f->value.l.high = 0;
1050 /* read attributes */
1051 if (!suck_check_classbuffer_size(cb, 2))
1054 attrnum = suck_u2(cb);
1055 for (i = 0; i < attrnum; i++) {
1056 if (!suck_check_classbuffer_size(cb, 2))
1059 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1062 if (u == utf_ConstantValue) {
1063 if (!suck_check_classbuffer_size(cb, 4 + 2))
1066 /* check attribute length */
1068 if (suck_u4(cb) != 2) {
1069 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1073 /* constant value attribute */
1075 if (pindex != field_load_NOVALUE) {
1076 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1080 /* index of value in constantpool */
1082 pindex = suck_u2(cb);
1084 /* initialize field with value from constantpool */
1087 constant_integer *ci;
1089 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1092 f->value.i = ci->value;
1099 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1102 f->value.l = cl->value;
1109 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1112 f->value.f = cf->value;
1117 constant_double *cd;
1119 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1122 f->value.d = cd->value;
1127 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1130 /* create javastring from compressed utf8-string */
1131 f->value.a = literalstring_new(u);
1135 log_text("Invalid Constant - Type");
1138 #if defined(ENABLE_JAVASE)
1139 else if (u == utf_Signature) {
1142 if (!loader_load_attribute_signature(cb, &(f->signature)))
1147 /* unknown attribute */
1149 if (!loader_skip_attribute_body(cb))
1154 /* everything was ok */
1160 /* loader_load_method **********************************************************
1162 Loads a method from the class file and fills an existing
1163 'methodinfo' structure. For native methods, the function pointer
1164 field is set to the real function pointer, for JavaVM methods a
1165 pointer to the compiler is used preliminarily.
1170 u2 descriptor_index;
1171 u2 attributes_count;
1172 attribute_info attributes[attribute_count];
1176 u2 attribute_name_index;
1177 u4 attribute_length;
1178 u1 info[attribute_length];
1181 LineNumberTable_attribute {
1182 u2 attribute_name_index;
1183 u4 attribute_length;
1184 u2 line_number_table_length;
1188 } line_number_table[line_number_table_length];
1191 *******************************************************************************/
1193 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1194 descriptor_pool *descpool)
1201 u2 descriptor_index;
1202 u2 attributes_count;
1203 u2 attribute_name_index;
1204 utf *attribute_name;
1205 u2 code_attributes_count;
1206 u2 code_attribute_name_index;
1207 utf *code_attribute_name;
1213 #if defined(ENABLE_THREADS)
1214 lock_init_object_lock(&m->header);
1217 #if defined(ENABLE_STATISTICS)
1219 count_all_methods++;
1222 /* all fields of m have been zeroed in load_class_from_classbuffer */
1226 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1231 m->flags = suck_u2(cb);
1235 name_index = suck_u2(cb);
1237 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1244 descriptor_index = suck_u2(cb);
1246 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1251 if (!descriptor_pool_add(descpool, u, &argcount))
1254 #ifdef ENABLE_VERIFIER
1256 if (!is_valid_name_utf(m->name)) {
1257 exceptions_throw_classformaterror(c, "Method with invalid name");
1261 if (m->name->text[0] == '<' &&
1262 m->name != utf_init && m->name != utf_clinit) {
1263 exceptions_throw_classformaterror(c, "Method with invalid special name");
1267 #endif /* ENABLE_VERIFIER */
1269 if (!(m->flags & ACC_STATIC))
1270 argcount++; /* count the 'this' argument */
1272 #ifdef ENABLE_VERIFIER
1274 if (argcount > 255) {
1275 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1279 /* check flag consistency */
1280 if (m->name != utf_clinit) {
1281 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1283 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1284 exceptions_throw_classformaterror(c,
1285 "Illegal method modifiers: 0x%X",
1290 if (m->flags & ACC_ABSTRACT) {
1291 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1292 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1293 exceptions_throw_classformaterror(c,
1294 "Illegal method modifiers: 0x%X",
1300 if (c->flags & ACC_INTERFACE) {
1301 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1302 exceptions_throw_classformaterror(c,
1303 "Illegal method modifiers: 0x%X",
1309 if (m->name == utf_init) {
1310 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1311 ACC_NATIVE | ACC_ABSTRACT)) {
1312 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1318 #endif /* ENABLE_VERIFIER */
1320 /* mark the method as monomorphic until further notice */
1322 m->flags |= ACC_METHOD_MONOMORPHIC;
1324 /* non-abstract methods have an implementation in this class */
1326 if (!(m->flags & ACC_ABSTRACT))
1327 m->flags |= ACC_METHOD_IMPLEMENTED;
1329 if (!suck_check_classbuffer_size(cb, 2))
1332 /* attributes count */
1334 attributes_count = suck_u2(cb);
1336 for (i = 0; i < attributes_count; i++) {
1337 if (!suck_check_classbuffer_size(cb, 2))
1340 /* attribute name index */
1342 attribute_name_index = suck_u2(cb);
1344 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1347 if (attribute_name == utf_Code) {
1349 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1350 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1355 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1359 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1363 m->maxstack = suck_u2(cb);
1364 m->maxlocals = suck_u2(cb);
1366 if (m->maxlocals < argcount) {
1367 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1371 if (!suck_check_classbuffer_size(cb, 4))
1374 m->jcodelength = suck_u4(cb);
1376 if (m->jcodelength == 0) {
1377 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1381 if (m->jcodelength > 65535) {
1382 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1386 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1389 m->jcode = MNEW(u1, m->jcodelength);
1390 suck_nbytes(m->jcode, cb, m->jcodelength);
1392 if (!suck_check_classbuffer_size(cb, 2))
1395 m->rawexceptiontablelength = suck_u2(cb);
1396 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1399 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1401 #if defined(ENABLE_STATISTICS)
1403 count_vmcode_len += m->jcodelength + 18;
1404 count_extable_len +=
1405 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1409 for (j = 0; j < m->rawexceptiontablelength; j++) {
1411 m->rawexceptiontable[j].startpc = suck_u2(cb);
1412 m->rawexceptiontable[j].endpc = suck_u2(cb);
1413 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1417 m->rawexceptiontable[j].catchtype.any = NULL;
1420 /* the classref is created later */
1421 if (!(m->rawexceptiontable[j].catchtype.any =
1422 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1427 if (!suck_check_classbuffer_size(cb, 2))
1430 /* code attributes count */
1432 code_attributes_count = suck_u2(cb);
1434 for (k = 0; k < code_attributes_count; k++) {
1435 if (!suck_check_classbuffer_size(cb, 2))
1438 /* code attribute name index */
1440 code_attribute_name_index = suck_u2(cb);
1442 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1445 /* check which code attribute */
1447 if (code_attribute_name == utf_LineNumberTable) {
1448 /* LineNumberTable */
1449 if (!suck_check_classbuffer_size(cb, 4 + 2))
1452 /* attribute length */
1456 /* line number table length */
1458 m->linenumbercount = suck_u2(cb);
1460 if (!suck_check_classbuffer_size(cb,
1461 (2 + 2) * m->linenumbercount))
1464 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1466 #if defined(ENABLE_STATISTICS)
1468 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1471 for (l = 0; l < m->linenumbercount; l++) {
1472 m->linenumbers[l].start_pc = suck_u2(cb);
1473 m->linenumbers[l].line_number = suck_u2(cb);
1476 #if defined(ENABLE_JAVASE)
1477 else if (code_attribute_name == utf_StackMapTable) {
1480 if (!stackmap_load_attribute_stackmaptable(cb, m))
1485 /* unknown code attribute */
1487 if (!loader_skip_attribute_body(cb))
1492 else if (attribute_name == utf_Exceptions) {
1495 if (m->thrownexceptions != NULL) {
1496 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1500 if (!suck_check_classbuffer_size(cb, 4 + 2))
1503 /* attribute length */
1507 m->thrownexceptionscount = suck_u2(cb);
1509 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1512 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1514 for (j = 0; j < m->thrownexceptionscount; j++) {
1515 /* the classref is created later */
1516 if (!((m->thrownexceptions)[j].any =
1517 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1521 #if defined(ENABLE_JAVASE)
1522 else if (attribute_name == utf_Signature) {
1525 if (!loader_load_attribute_signature(cb, &(m->signature)))
1530 /* unknown attribute */
1532 if (!loader_skip_attribute_body(cb))
1537 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1538 exceptions_throw_classformaterror(c, "Missing Code attribute");
1542 /* initialize the hit countdown field */
1544 #if defined(ENABLE_REPLACEMENT)
1545 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1548 /* everything was ok */
1554 /* load_class_from_sysloader ***************************************************
1556 Load the class with the given name using the system class loader
1559 name.............the classname
1562 the loaded class, or
1563 NULL if an exception has been thrown
1565 *******************************************************************************/
1567 classinfo *load_class_from_sysloader(utf *name)
1570 java_objectheader *clo;
1574 assert(class_java_lang_Object);
1575 assert(class_java_lang_ClassLoader);
1576 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1578 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1579 utf_getSystemClassLoader,
1580 utf_void__java_lang_ClassLoader,
1581 class_java_lang_Object,
1587 clo = vm_call_method(m, NULL);
1592 cl = loader_hashtable_classloader_add(clo);
1594 c = load_class_from_classloader(name, cl);
1600 /* load_class_from_classloader *************************************************
1602 Load the class with the given name using the given user-defined class loader.
1605 name.............the classname
1606 cl...............user-defined class loader
1609 the loaded class, or
1610 NULL if an exception has been thrown
1612 *******************************************************************************/
1614 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1616 java_objectheader *o;
1619 java_objectheader *string;
1620 #if defined(ENABLE_RT_TIMING)
1621 struct timespec time_start, time_lookup, time_prepare, time_java,
1625 RT_TIMING_GET_TIME(time_start);
1629 /* lookup if this class has already been loaded */
1631 c = classcache_lookup(cl, name);
1633 RT_TIMING_GET_TIME(time_lookup);
1634 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1639 /* if other class loader than bootstrap, call it */
1647 namelen = name->blength;
1649 /* handle array classes */
1650 if (text[0] == '[') {
1656 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1657 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1658 exceptions_throw_noclassdeffounderror(name);
1662 u = utf_new(text + 2, namelen - 3);
1664 if (!(comp = load_class_from_classloader(u, cl)))
1667 /* create the array class */
1669 c = class_array_of(comp, false);
1671 tmpc = classcache_store(cl, c, true);
1674 /* exception, free the loaded class */
1675 c->state &= ~CLASS_LOADING;
1682 /* load the component class */
1684 u = utf_new(text + 1, namelen - 1);
1686 if (!(comp = load_class_from_classloader(u, cl)))
1689 /* create the array class */
1691 c = class_array_of(comp, false);
1693 tmpc = classcache_store(cl, c, true);
1696 /* exception, free the loaded class */
1697 c->state &= ~CLASS_LOADING;
1704 /* primitive array classes are loaded by the bootstrap loader */
1706 c = load_class_bootstrap(name);
1712 assert(class_java_lang_Object);
1714 lc = class_resolveclassmethod(cl->object->vftbl->class,
1716 utf_java_lang_String__java_lang_Class,
1717 class_java_lang_Object,
1721 return false; /* exception */
1723 /* move return value into `o' and cast it afterwards to a classinfo* */
1725 string = javastring_new_slash_to_dot(name);
1727 RT_TIMING_GET_TIME(time_prepare);
1729 o = vm_call_method(lc, cl->object, string);
1731 RT_TIMING_GET_TIME(time_java);
1733 c = (classinfo *) o;
1736 /* Store this class in the loaded class cache. If another
1737 class with the same (initloader,name) pair has been
1738 stored earlier it will be returned by classcache_store
1739 In this case classcache_store may not free the class
1740 because it has already been exposed to Java code which
1741 may have kept references to that class. */
1743 tmpc = classcache_store(cl, c, false);
1746 /* exception, free the loaded class */
1747 c->state &= ~CLASS_LOADING;
1754 /* loadClass has thrown an exception. We must convert
1755 ClassNotFoundException into
1756 NoClassDefFoundException. */
1758 /* XXX Maybe we should have a flag that avoids this
1759 conversion for calling load_class_from_classloader from
1760 Class.forName. Currently we do a double conversion in
1763 classnotfoundexception_to_noclassdeffounderror();
1766 RT_TIMING_GET_TIME(time_cache);
1768 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1769 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1770 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1772 /* SUN compatible -verbose:class output */
1774 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1776 utf_display_printable_ascii_classname(name);
1780 #if defined(ENABLE_JVMTI)
1781 /* fire Class Load JVMTI event */
1782 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1789 c = load_class_bootstrap(name);
1795 /* load_class_bootstrap ********************************************************
1797 Load the class with the given name using the bootstrap class loader.
1800 name.............the classname
1803 loaded classinfo, or
1804 NULL if an exception has been thrown
1807 load_class_bootstrap is synchronized. It can be treated as an
1810 *******************************************************************************/
1812 classinfo *load_class_bootstrap(utf *name)
1817 #if defined(ENABLE_RT_TIMING)
1818 struct timespec time_start, time_lookup, time_array, time_suck,
1819 time_load, time_cache;
1822 RT_TIMING_GET_TIME(time_start);
1828 /* lookup if this class has already been loaded */
1830 if ((r = classcache_lookup(NULL, name))) {
1832 RT_TIMING_GET_TIME(time_lookup);
1833 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1838 RT_TIMING_GET_TIME(time_lookup);
1839 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1841 /* create the classinfo */
1843 c = class_create_classinfo(name);
1845 /* handle array classes */
1847 if (name->text[0] == '[') {
1848 c = load_newly_created_array(c, NULL);
1851 assert(c->state & CLASS_LOADED);
1853 RT_TIMING_GET_TIME(time_array);
1854 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1859 #if defined(ENABLE_STATISTICS)
1862 if (opt_getcompilingtime)
1863 compilingtime_stop();
1865 if (opt_getloadingtime)
1866 loadingtime_start();
1869 /* load classdata, throw exception on error */
1874 /* this normally means, the classpath was not set properly */
1876 if (name == utf_java_lang_Object)
1877 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1879 exceptions_throw_noclassdeffounderror(name);
1884 RT_TIMING_GET_TIME(time_suck);
1886 /* load the class from the buffer */
1888 r = load_class_from_classbuffer(cb);
1890 RT_TIMING_GET_TIME(time_load);
1893 /* the class could not be loaded, free the classinfo struct */
1898 /* Store this class in the loaded class cache this step also
1899 checks the loading constraints. If the class has been loaded
1900 before, the earlier loaded class is returned. */
1902 classinfo *res = classcache_store(NULL, c, true);
1912 RT_TIMING_GET_TIME(time_cache);
1914 /* SUN compatible -verbose:class output */
1916 if (opt_verboseclass && r) {
1918 utf_display_printable_ascii_classname(name);
1919 printf(" from %s]\n", cb->path);
1926 #if defined(ENABLE_STATISTICS)
1929 if (opt_getloadingtime)
1932 if (opt_getcompilingtime)
1933 compilingtime_start();
1936 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1937 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1938 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1939 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1945 /* load_class_from_classbuffer *************************************************
1947 Loads everything interesting about a class from the class file. The
1948 'classinfo' structure must have been allocated previously.
1950 The super class and the interfaces implemented by this class need
1951 not be loaded. The link is set later by the function 'class_link'.
1953 The loaded class is removed from the list 'unloadedclasses' and
1954 added to the list 'unlinkedclasses'.
1957 This function is NOT synchronized!
1959 *******************************************************************************/
1961 classinfo *load_class_from_classbuffer(classbuffer *cb)
1969 descriptor_pool *descpool;
1970 #if defined(ENABLE_STATISTICS)
1974 #if defined(ENABLE_RT_TIMING)
1975 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1976 time_setup, time_fields, time_methods, time_classrefs,
1977 time_descs, time_setrefs, time_parsefds, time_parsemds,
1978 time_parsecpool, time_verify, time_attrs;
1981 RT_TIMING_GET_TIME(time_start);
1983 /* get the classbuffer's class */
1987 /* the class is already loaded */
1989 if (c->state & CLASS_LOADED)
1992 #if defined(ENABLE_STATISTICS)
1994 count_class_loads++;
1997 #if !defined(NDEBUG)
1998 /* output for debugging purposes */
2001 log_message_class("Loading class: ", c);
2004 /* mark start of dump memory area */
2006 dumpsize = dump_size();
2008 /* class is currently loading */
2010 c->state |= CLASS_LOADING;
2012 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2013 goto return_exception;
2015 /* check signature */
2017 if (suck_u4(cb) != MAGIC) {
2018 exceptions_throw_classformaterror(c, "Bad magic number");
2020 goto return_exception;
2028 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2029 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2030 goto return_exception;
2033 RT_TIMING_GET_TIME(time_checks);
2035 /* create a new descriptor pool */
2037 descpool = descriptor_pool_new(c);
2039 RT_TIMING_GET_TIME(time_ndpool);
2041 /* load the constant pool */
2043 if (!load_constantpool(cb, descpool))
2044 goto return_exception;
2046 RT_TIMING_GET_TIME(time_cpool);
2050 if (!suck_check_classbuffer_size(cb, 2))
2051 goto return_exception;
2053 /* We OR the flags here, as we set already some flags in
2054 class_create_classinfo. */
2056 c->flags |= suck_u2(cb);
2058 /* check ACC flags consistency */
2060 if (c->flags & ACC_INTERFACE) {
2061 if (!(c->flags & ACC_ABSTRACT)) {
2062 /* We work around this because interfaces in JDK 1.1 are
2063 * not declared abstract. */
2065 c->flags |= ACC_ABSTRACT;
2068 if (c->flags & ACC_FINAL) {
2069 exceptions_throw_classformaterror(c,
2070 "Illegal class modifiers: 0x%X",
2072 goto return_exception;
2075 if (c->flags & ACC_SUPER) {
2076 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2080 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2081 exceptions_throw_classformaterror(c,
2082 "Illegal class modifiers: 0x%X",
2084 goto return_exception;
2087 if (!suck_check_classbuffer_size(cb, 2 + 2))
2088 goto return_exception;
2094 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2095 goto return_exception;
2097 if (c->name == utf_not_named_yet) {
2098 /* we finally have a name for this class */
2100 class_set_packagename(c);
2102 else if (name != c->name) {
2103 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
2104 goto return_exception;
2107 /* retrieve superclass */
2109 c->super.any = NULL;
2111 if ((i = suck_u2(cb))) {
2112 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2113 goto return_exception;
2115 /* java.lang.Object may not have a super class. */
2117 if (c->name == utf_java_lang_Object) {
2118 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2119 goto return_exception;
2122 /* Interfaces must have java.lang.Object as super class. */
2124 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2125 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2126 goto return_exception;
2132 /* This is only allowed for java.lang.Object. */
2134 if (c->name != utf_java_lang_Object) {
2135 exceptions_throw_classformaterror(c, "Bad superclass index");
2136 goto return_exception;
2140 /* retrieve interfaces */
2142 if (!suck_check_classbuffer_size(cb, 2))
2143 goto return_exception;
2145 c->interfacescount = suck_u2(cb);
2147 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2148 goto return_exception;
2150 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2151 for (i = 0; i < c->interfacescount; i++) {
2152 /* the classrefs are created later */
2153 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2154 goto return_exception;
2157 RT_TIMING_GET_TIME(time_setup);
2160 if (!suck_check_classbuffer_size(cb, 2))
2161 goto return_exception;
2163 c->fieldscount = suck_u2(cb);
2164 #if defined(ENABLE_GC_CACAO)
2165 c->fields = MNEW(fieldinfo, c->fieldscount);
2166 MZERO(c->fields, fieldinfo, c->fieldscount);
2168 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2171 for (i = 0; i < c->fieldscount; i++) {
2172 if (!load_field(cb, &(c->fields[i]),descpool))
2173 goto return_exception;
2176 RT_TIMING_GET_TIME(time_fields);
2179 if (!suck_check_classbuffer_size(cb, 2))
2180 goto return_exception;
2182 c->methodscount = suck_u2(cb);
2183 c->methods = MNEW(methodinfo, c->methodscount);
2185 MZERO(c->methods, methodinfo, c->methodscount);
2187 for (i = 0; i < c->methodscount; i++) {
2188 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2189 goto return_exception;
2192 RT_TIMING_GET_TIME(time_methods);
2194 /* create the class reference table */
2197 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2199 RT_TIMING_GET_TIME(time_classrefs);
2201 /* allocate space for the parsed descriptors */
2203 descriptor_pool_alloc_parsed_descriptors(descpool);
2205 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2207 #if defined(ENABLE_STATISTICS)
2209 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2210 count_classref_len += classrefsize;
2211 count_parsed_desc_len += descsize;
2215 RT_TIMING_GET_TIME(time_descs);
2217 /* put the classrefs in the constant pool */
2218 for (i = 0; i < c->cpcount; i++) {
2219 if (c->cptags[i] == CONSTANT_Class) {
2220 utf *name = (utf *) c->cpinfos[i];
2221 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2225 /* set the super class reference */
2228 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2230 goto return_exception;
2233 /* set the super interfaces references */
2235 for (i = 0; i < c->interfacescount; i++) {
2236 c->interfaces[i].ref =
2237 descriptor_pool_lookup_classref(descpool,
2238 (utf *) c->interfaces[i].any);
2239 if (!c->interfaces[i].ref)
2240 goto return_exception;
2243 RT_TIMING_GET_TIME(time_setrefs);
2245 /* parse field descriptors */
2247 for (i = 0; i < c->fieldscount; i++) {
2248 c->fields[i].parseddesc =
2249 descriptor_pool_parse_field_descriptor(descpool,
2250 c->fields[i].descriptor);
2251 if (!c->fields[i].parseddesc)
2252 goto return_exception;
2255 RT_TIMING_GET_TIME(time_parsefds);
2257 /* parse method descriptors */
2259 for (i = 0; i < c->methodscount; i++) {
2260 methodinfo *m = &c->methods[i];
2262 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2263 m->flags, class_get_self_classref(m->class));
2265 goto return_exception;
2267 for (j = 0; j < m->rawexceptiontablelength; j++) {
2268 if (!m->rawexceptiontable[j].catchtype.any)
2270 if ((m->rawexceptiontable[j].catchtype.ref =
2271 descriptor_pool_lookup_classref(descpool,
2272 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2273 goto return_exception;
2276 for (j = 0; j < m->thrownexceptionscount; j++) {
2277 if (!m->thrownexceptions[j].any)
2279 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2280 (utf *) m->thrownexceptions[j].any)) == NULL)
2281 goto return_exception;
2285 RT_TIMING_GET_TIME(time_parsemds);
2287 /* parse the loaded descriptors */
2289 for (i = 0; i < c->cpcount; i++) {
2290 constant_FMIref *fmi;
2293 switch (c->cptags[i]) {
2294 case CONSTANT_Fieldref:
2295 fmi = (constant_FMIref *) c->cpinfos[i];
2296 fmi->parseddesc.fd =
2297 descriptor_pool_parse_field_descriptor(descpool,
2299 if (!fmi->parseddesc.fd)
2300 goto return_exception;
2301 index = fmi->p.index;
2303 (constant_classref *) class_getconstant(c, index,
2305 if (!fmi->p.classref)
2306 goto return_exception;
2308 case CONSTANT_Methodref:
2309 case CONSTANT_InterfaceMethodref:
2310 fmi = (constant_FMIref *) c->cpinfos[i];
2311 index = fmi->p.index;
2313 (constant_classref *) class_getconstant(c, index,
2315 if (!fmi->p.classref)
2316 goto return_exception;
2317 fmi->parseddesc.md =
2318 descriptor_pool_parse_method_descriptor(descpool,
2322 if (!fmi->parseddesc.md)
2323 goto return_exception;
2328 RT_TIMING_GET_TIME(time_parsecpool);
2330 #ifdef ENABLE_VERIFIER
2331 /* Check if all fields and methods can be uniquely
2332 * identified by (name,descriptor). */
2335 /* We use a hash table here to avoid making the
2336 * average case quadratic in # of methods, fields.
2338 static int shift = 0;
2340 u2 *next; /* for chaining colliding hash entries */
2346 /* Allocate hashtable */
2347 len = c->methodscount;
2348 if (len < c->fieldscount) len = c->fieldscount;
2350 hashtab = MNEW(u2,(hashlen + len));
2351 next = hashtab + hashlen;
2353 /* Determine bitshift (to get good hash values) */
2363 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2365 for (i = 0; i < c->fieldscount; ++i) {
2366 fieldinfo *fi = c->fields + i;
2368 /* It's ok if we lose bits here */
2369 index = ((((size_t) fi->name) +
2370 ((size_t) fi->descriptor)) >> shift) % hashlen;
2372 if ((old = hashtab[index])) {
2376 if (c->fields[old].name == fi->name &&
2377 c->fields[old].descriptor == fi->descriptor) {
2378 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2379 goto return_exception;
2381 } while ((old = next[old]));
2383 hashtab[index] = i + 1;
2387 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2389 for (i = 0; i < c->methodscount; ++i) {
2390 methodinfo *mi = c->methods + i;
2392 /* It's ok if we lose bits here */
2393 index = ((((size_t) mi->name) +
2394 ((size_t) mi->descriptor)) >> shift) % hashlen;
2398 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2399 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2403 if ((old = hashtab[index])) {
2407 if (c->methods[old].name == mi->name &&
2408 c->methods[old].descriptor == mi->descriptor) {
2409 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2410 goto return_exception;
2412 } while ((old = next[old]));
2414 hashtab[index] = i + 1;
2417 MFREE(hashtab, u2, (hashlen + len));
2419 #endif /* ENABLE_VERIFIER */
2421 RT_TIMING_GET_TIME(time_verify);
2423 #if defined(ENABLE_STATISTICS)
2425 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2426 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2427 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2431 /* load attribute structures */
2433 if (!class_load_attributes(cb))
2434 goto return_exception;
2436 /* Pre Java 1.5 version don't check this. This implementation is like
2437 Java 1.5 do it: for class file version 45.3 we don't check it, older
2438 versions are checked.
2441 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2442 /* check if all data has been read */
2443 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2445 if (classdata_left > 0) {
2446 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2447 goto return_exception;
2451 RT_TIMING_GET_TIME(time_attrs);
2453 /* release dump area */
2455 dump_release(dumpsize);
2457 /* revert loading state and class is loaded */
2459 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2461 #if defined(ENABLE_JVMTI)
2462 /* fire Class Prepare JVMTI event */
2465 jvmti_ClassLoadPrepare(true, c);
2468 #if !defined(NDEBUG)
2470 log_message_class("Loading done class: ", c);
2473 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2474 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2475 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2476 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2477 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2478 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2479 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2480 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2481 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2482 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2483 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2484 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2485 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2486 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2487 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2492 /* release dump area */
2494 dump_release(dumpsize);
2496 /* an exception has been thrown */
2502 /* load_newly_created_array ****************************************************
2504 Load a newly created array class.
2507 c....................the array class C has been loaded
2508 other classinfo......the array class was found in the class cache,
2510 NULL.................an exception has been thrown
2513 This is an internal function. Do not use it unless you know exactly
2516 Use one of the load_class_... functions for general array class loading.
2518 *******************************************************************************/
2520 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2522 classinfo *comp = NULL;
2524 methoddesc *clonedesc;
2525 constant_classref *classrefs;
2530 text = c->name->text;
2531 namelen = c->name->blength;
2533 /* Check array class name */
2535 if ((namelen < 2) || (text[0] != '[')) {
2536 exceptions_throw_noclassdeffounderror(c->name);
2540 /* Check the element type */
2544 /* c is an array of arrays. We have to create the component class. */
2546 u = utf_new(text + 1, namelen - 1);
2547 if (!(comp = load_class_from_classloader(u, loader)))
2550 assert(comp->state & CLASS_LOADED);
2556 /* the array's flags are that of the component class */
2557 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2558 c->classloader = comp->classloader;
2562 /* c is an array of objects. */
2564 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2565 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2566 exceptions_throw_noclassdeffounderror(c->name);
2570 u = utf_new(text + 2, namelen - 3);
2572 if (!(comp = load_class_from_classloader(u, loader)))
2575 assert(comp->state & CLASS_LOADED);
2581 /* the array's flags are that of the component class */
2582 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2583 c->classloader = comp->classloader;
2587 /* c is an array of a primitive type */
2589 /* check for cases like `[II' */
2591 exceptions_throw_noclassdeffounderror(c->name);
2595 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2596 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2597 c->classloader = NULL;
2600 assert(class_java_lang_Object);
2601 #if defined(ENABLE_JAVASE)
2602 assert(class_java_lang_Cloneable);
2603 assert(class_java_io_Serializable);
2606 /* setup the array class */
2608 c->super.cls = class_java_lang_Object;
2610 #if defined(ENABLE_JAVASE)
2611 c->interfacescount = 2;
2612 c->interfaces = MNEW(classref_or_classinfo, 2);
2617 tc = class_java_lang_Cloneable;
2618 assert(tc->state & CLASS_LOADED);
2619 list_add_first(&unlinkedclasses, tc);
2620 c->interfaces[0].cls = tc;
2622 tc = class_java_io_Serializable;
2623 assert(tc->state & CLASS_LOADED);
2624 list_add_first(&unlinkedclasses, tc);
2625 c->interfaces[1].cls = tc;
2628 c->interfaces[0].cls = class_java_lang_Cloneable;
2629 c->interfaces[1].cls = class_java_io_Serializable;
2631 #elif defined(ENABLE_JAVAME_CLDC1_1)
2632 c->interfacescount = 0;
2633 c->interfaces = NULL;
2635 #error unknow Java configuration
2638 c->methodscount = 1;
2639 c->methods = MNEW(methodinfo, c->methodscount);
2640 MZERO(c->methods, methodinfo, c->methodscount);
2642 classrefs = MNEW(constant_classref, 2);
2643 CLASSREF_INIT(classrefs[0], c, c->name);
2644 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2646 /* create descriptor for clone method */
2647 /* we need one paramslot which is reserved for the 'this' parameter */
2648 clonedesc = NEW(methoddesc);
2649 clonedesc->returntype.type = TYPE_ADR;
2650 clonedesc->returntype.classref = classrefs + 1;
2651 clonedesc->returntype.arraydim = 0;
2652 /* initialize params to "empty", add real params below in
2653 descriptor_params_from_paramtypes */
2654 clonedesc->paramcount = 0;
2655 clonedesc->paramslots = 0;
2656 clonedesc->paramtypes[0].classref = classrefs + 0;
2657 clonedesc->params = NULL;
2659 /* create methodinfo */
2662 MSET(clone, 0, methodinfo, 1);
2664 #if defined(ENABLE_THREADS)
2665 lock_init_object_lock(&clone->header);
2668 /* ATTENTION: if you delete the ACC_NATIVE below, set
2669 clone->maxlocals=1 (interpreter related) */
2671 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2672 clone->name = utf_clone;
2673 clone->descriptor = utf_void__java_lang_Object;
2674 clone->parseddesc = clonedesc;
2677 /* parse the descriptor to get the register allocation */
2679 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2682 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2684 /* XXX: field: length? */
2686 /* array classes are not loaded from class files */
2688 c->state |= CLASS_LOADED;
2689 c->parseddescs = (u1 *) clonedesc;
2690 c->parseddescsize = sizeof(methodinfo);
2691 c->classrefs = classrefs;
2692 c->classrefcount = 1;
2694 /* insert class into the loaded class cache */
2695 /* XXX free classinfo if NULL returned? */
2697 return classcache_store(loader, c, true);
2701 /* loader_close ****************************************************************
2703 Frees all resources.
2705 *******************************************************************************/
2707 void loader_close(void)
2714 * These are local overrides for various environment variables in Emacs.
2715 * Please do not remove this and leave it at the end of the file, where
2716 * Emacs will automagically detect them.
2717 * ---------------------------------------------------------------------
2720 * indent-tabs-mode: t
2724 * vim:noexpandtab:sw=4:ts=4: