1 /* src/vm/class.c - class related functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
33 $Id: class.c 2193 2005-04-02 19:33:43Z edwin $
40 #include "vm/global.h"
41 #include "mm/memory.h"
43 #if defined(USE_THREADS)
44 # if defined(NATIVE_THREADS)
45 # include "threads/native/threads.h"
47 # include "threads/green/threads.h"
48 # include "threads/green/locks.h"
52 #include "toolbox/logging.h"
54 #include "vm/options.h"
55 #include "vm/resolve.h"
56 #include "vm/statistics.h"
57 #include "vm/tables.h"
59 #include "vm/loader.h"
62 /******************************************************************************/
64 /******************************************************************************/
71 #define CLASS_ASSERT(cond) assert(cond)
73 #define CLASS_ASSERT(cond)
77 /* global variables ***********************************************************/
79 hashtable class_hash; /* hashtable for classes */
81 list unlinkedclasses; /* this is only used for eager class */
85 /* frequently used classes ****************************************************/
87 /* important system classes */
89 classinfo *class_java_lang_Object = NULL;
90 classinfo *class_java_lang_Class = NULL;
91 classinfo *class_java_lang_ClassLoader = NULL;
92 classinfo *class_java_lang_Cloneable = NULL;
93 classinfo *class_java_lang_SecurityManager = NULL;
94 classinfo *class_java_lang_String = NULL;
95 classinfo *class_java_lang_System = NULL;
96 classinfo *class_java_io_Serializable = NULL;
99 /* system exception classes required in cacao */
101 classinfo *class_java_lang_Throwable = NULL;
102 classinfo *class_java_lang_VMThrowable = NULL;
103 classinfo *class_java_lang_Exception = NULL;
104 classinfo *class_java_lang_Error = NULL;
105 classinfo *class_java_lang_OutOfMemoryError = NULL;
106 classinfo *class_java_lang_NoClassDefFoundError = NULL;
108 classinfo *class_java_lang_Void = NULL;
109 classinfo *class_java_lang_Boolean = NULL;
110 classinfo *class_java_lang_Byte = NULL;
111 classinfo *class_java_lang_Character = NULL;
112 classinfo *class_java_lang_Short = NULL;
113 classinfo *class_java_lang_Integer = NULL;
114 classinfo *class_java_lang_Long = NULL;
115 classinfo *class_java_lang_Float = NULL;
116 classinfo *class_java_lang_Double = NULL;
118 /* some classes which may be used more often */
120 classinfo *class_java_util_Vector = NULL;
123 /* pseudo classes for the typechecker */
125 classinfo *pseudo_class_Arraystub = NULL;
126 classinfo *pseudo_class_Null = NULL;
127 classinfo *pseudo_class_New = NULL;
129 /* class_new *******************************************************************
131 Searches for the class with the specified name in the classes
132 hashtable, if there is no such class a new classinfo structure is
133 created and inserted into the list of classes to be loaded.
135 *******************************************************************************/
137 classinfo *class_new(utf *classname)
141 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
145 /* we support eager class loading and linking on demand */
150 list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
152 if (!load_class_bootstrap(classname,&c)) {
153 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
159 /* link all referenced classes */
161 tc = list_first(&unlinkedclasses);
164 /* skip the current loaded/linked class */
166 if (!link_class(tc)) {
167 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
174 /* we need a tmp variable here, because list_remove sets prev and
176 tmp = list_next(&unlinkedclasses, tc);
177 list_remove(&unlinkedclasses, tc);
182 if (!link_class(c)) {
183 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
191 c = class_new_intern(classname);
195 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
203 classinfo *class_new_intern(utf *classname)
205 classinfo *c; /* hashtable element */
206 u4 key; /* hashkey computed from classname */
207 u4 slot; /* slot in hashtable */
210 key = utf_hashkey(classname->text, classname->blength);
211 slot = key & (class_hash.size - 1);
212 c = class_hash.ptr[slot];
214 /* search external hash chain for the class */
216 if (c->name->blength == classname->blength) {
217 for (i = 0; i < classname->blength; i++)
218 if (classname->text[i] != c->name->text[i]) goto nomatch;
220 /* class found in hashtable */
225 c = c->hashlink; /* next element in external chain */
228 /* location in hashtable found, create new classinfo structure */
230 #if defined(STATISTICS)
232 count_class_infos += sizeof(classinfo);
236 char logtext[MAXLOGTEXT];
237 sprintf(logtext, "Creating class: ");
238 utf_sprint_classname(logtext + strlen(logtext), classname);
242 c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
243 /*c=NEW(classinfo);*/
247 c->packagename = NULL;
252 c->extclassrefs = NULL;
253 c->classrefcount = 0;
254 c->parseddescs = NULL;
255 c->parseddescsize = 0;
259 c->interfacescount = 0;
260 c->interfaces = NULL;
269 c->header.vftbl = NULL;
270 c->innerclasscount = 0;
271 c->innerclass = NULL;
273 c->initialized = false;
274 c->initializing = false;
275 c->classvftbl = false;
278 c->classloader = NULL;
279 c->sourcefile = NULL;
281 /* insert class into the hashtable */
282 c->hashlink = class_hash.ptr[slot];
283 class_hash.ptr[slot] = c;
285 /* update number of hashtable-entries */
286 class_hash.entries++;
288 if (class_hash.entries > (class_hash.size * 2)) {
290 /* reorganization of hashtable, average length of
291 the external chains is approx. 2 */
295 hashtable newhash; /* the new hashtable */
297 /* create new hashtable, double the size */
298 init_hashtable(&newhash, class_hash.size * 2);
299 newhash.entries = class_hash.entries;
301 /* transfer elements to new hashtable */
302 for (i = 0; i < class_hash.size; i++) {
303 c = (classinfo *) class_hash.ptr[i];
305 classinfo *nextc = c->hashlink;
306 u4 slot = (utf_hashkey(c->name->text, c->name->blength)) & (newhash.size - 1);
308 c->hashlink = newhash.ptr[slot];
309 newhash.ptr[slot] = c;
315 /* dispose old table */
316 MFREE(class_hash.ptr, void*, class_hash.size);
317 class_hash = newhash;
320 /* Array classes need further initialization. */
321 if (c->name->text[0] == '[') {
322 /* Array classes are not loaded from classfiles. */
325 c->packagename = array_packagename;
328 /* Find the package name */
329 /* Classes in the unnamed package keep packagename == NULL. */
330 char *p = utf_end(c->name) - 1;
331 char *start = c->name->text;
332 for (;p > start; --p) {
334 c->packagename = utf_new (start, p - start);
340 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
341 initObjectLock(&c->header);
348 /* class_get *******************************************************************
350 Searches for the class with the specified name in the classes
351 hashtable if there is no such class NULL is returned.
353 *******************************************************************************/
355 classinfo *class_get(utf *classname)
357 classinfo *c; /* hashtable element */
358 u4 key; /* hashkey computed from classname */
359 u4 slot; /* slot in hashtable */
362 key = utf_hashkey(classname->text, classname->blength);
363 slot = key & (class_hash.size-1);
364 c = class_hash.ptr[slot];
366 /* search external hash-chain */
368 if (c->name->blength == classname->blength) {
369 /* compare classnames */
370 for (i = 0; i < classname->blength; i++)
371 if (classname->text[i] != c->name->text[i])
374 /* class found in hashtable */
382 /* class not found */
387 /* class_remove ****************************************************************
389 Removes the class entry wth the specified name in the classes
390 hashtable, furthermore the class' resources are freed if there is
391 no such class false is returned.
393 *******************************************************************************/
395 bool class_remove(classinfo *c)
397 classinfo *tc; /* hashtable element */
399 u4 key; /* hashkey computed from classname */
400 u4 slot; /* slot in hashtable */
403 key = utf_hashkey(c->name->text, c->name->blength);
404 slot = key & (class_hash.size - 1);
405 tc = class_hash.ptr[slot];
408 /* search external hash-chain */
410 if (tc->name->blength == c->name->blength) {
412 /* compare classnames */
413 for (i = 0; i < c->name->blength; i++)
414 if (tc->name->text[i] != c->name->text[i])
417 /* class found in hashtable */
419 class_hash.ptr[slot] = tc->hashlink;
421 pc->hashlink = tc->hashlink;
433 /* class not found */
438 /* class_freepool **************************************************************
440 Frees all resources used by this classes Constant Pool.
442 *******************************************************************************/
444 static void class_freecpool(classinfo *c)
450 if (c->cptags && c->cpinfos) {
451 for (idx = 0; idx < c->cpcount; idx++) {
452 tag = c->cptags[idx];
453 info = c->cpinfos[idx];
457 case CONSTANT_Fieldref:
458 case CONSTANT_Methodref:
459 case CONSTANT_InterfaceMethodref:
460 FREE(info, constant_FMIref);
462 case CONSTANT_Integer:
463 FREE(info, constant_integer);
466 FREE(info, constant_float);
469 FREE(info, constant_long);
471 case CONSTANT_Double:
472 FREE(info, constant_double);
474 case CONSTANT_NameAndType:
475 FREE(info, constant_nameandtype);
483 MFREE(c->cptags, u1, c->cpcount);
486 MFREE(c->cpinfos, voidptr, c->cpcount);
490 /* class_free ******************************************************************
492 Frees all resources used by the class.
494 *******************************************************************************/
496 void class_free(classinfo *c)
504 MFREE(c->interfaces, classinfo*, c->interfacescount);
507 for (i = 0; i < c->fieldscount; i++)
508 field_free(&(c->fields[i]));
509 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
513 for (i = 0; i < c->methodscount; i++)
514 method_free(&(c->methods[i]));
515 MFREE(c->methods, methodinfo, c->methodscount);
518 if ((v = c->vftbl) != NULL) {
520 mem_free(v->arraydesc,sizeof(arraydescriptor));
522 for (i = 0; i < v->interfacetablelength; i++) {
523 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
525 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
527 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
528 sizeof(methodptr*) * (v->interfacetablelength -
529 (v->interfacetablelength > 0));
530 v = (vftbl_t*) (((methodptr*) v) -
531 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
536 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
538 /* if (c->classvftbl)
539 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
545 /* class_array_of **************************************************************
547 Returns an array class with the given component class. The array
548 class is dynamically created if neccessary.
550 *******************************************************************************/
552 classinfo *class_array_of(classinfo *component)
558 /* Assemble the array class name */
559 namelen = component->name->blength;
561 if (component->name->text[0] == '[') {
562 /* the component is itself an array */
563 namebuf = DMNEW(char, namelen + 1);
565 MCOPY(namebuf + 1, component->name->text, char, namelen);
569 /* the component is a non-array class */
570 namebuf = DMNEW(char, namelen + 3);
573 MCOPY(namebuf + 2, component->name->text, char, namelen);
574 namebuf[2 + namelen] = ';';
578 c = class_new(utf_new(namebuf, namelen));
580 /* load this class and link it */
592 /* class_multiarray_of *********************************************************
594 Returns an array class with the given dimension and element class.
595 The array class is dynamically created if neccessary.
597 *******************************************************************************/
599 classinfo *class_multiarray_of(s4 dim, classinfo *element)
605 panic("Invalid array dimension requested");
607 /* Assemble the array class name */
608 namelen = element->name->blength;
610 if (element->name->text[0] == '[') {
611 /* the element is itself an array */
612 namebuf = DMNEW(char, namelen + dim);
613 memcpy(namebuf + dim, element->name->text, namelen);
617 /* the element is a non-array class */
618 namebuf = DMNEW(char, namelen + 2 + dim);
620 memcpy(namebuf + dim + 1, element->name->text, namelen);
621 namelen += (2 + dim);
622 namebuf[namelen - 1] = ';';
624 memset(namebuf, '[', dim);
626 return class_new(utf_new(namebuf, namelen));
629 /* class_lookup_classref *******************************************************
631 Looks up the constant_classref for a given classname in the classref
635 cls..............the class containing the reference
636 name.............the name of the class refered to
639 a pointer to a constant_classref, or
640 NULL if the reference was not found
642 *******************************************************************************/
644 constant_classref *class_lookup_classref(classinfo *cls,utf *name)
646 constant_classref *ref;
647 extra_classref *xref;
652 CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
654 /* first search the main classref table */
655 count = cls->classrefcount;
656 ref = cls->classrefs;
657 for (; count; --count, ++ref)
658 if (ref->name == name)
661 /* next try the list of extra classrefs */
662 for (xref=cls->extclassrefs; xref; xref=xref->next) {
663 if (xref->classref.name == name)
664 return &(xref->classref);
672 /* class_get_classref **********************************************************
674 Returns the constant_classref for a given classname.
677 cls..............the class containing the reference
678 name.............the name of the class refered to
681 a pointer to a constant_classref (never NULL)
684 The given name is not checked for validity!
686 *******************************************************************************/
688 constant_classref *class_get_classref(classinfo *cls,utf *name)
690 constant_classref *ref;
691 extra_classref *xref;
696 ref = class_lookup_classref(cls,name);
700 xref = NEW(extra_classref);
701 CLASSREF_INIT(xref->classref,cls,name);
703 xref->next = cls->extclassrefs;
704 cls->extclassrefs = xref;
706 return &(xref->classref);
709 /* class_get_classref_multiarray_of ********************************************
711 Returns an array type reference with the given dimension and element class
715 dim..............the requested dimension
716 dim must be in [1;255]. This is NOT checked!
717 ref..............the component class reference
720 a pointer to the class reference for the array type
723 The referer of `ref` is used as the referer for the new classref.
725 *******************************************************************************/
727 constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref)
733 CLASS_ASSERT(dim >= 1 && dim <= 255);
735 /* Assemble the array class name */
736 namelen = ref->name->blength;
738 if (ref->name->text[0] == '[') {
739 /* the element is itself an array */
740 namebuf = DMNEW(char, namelen + dim);
741 memcpy(namebuf + dim, ref->name->text, namelen);
745 /* the element is a non-array class */
746 namebuf = DMNEW(char, namelen + 2 + dim);
748 memcpy(namebuf + dim + 1, ref->name->text, namelen);
749 namelen += (2 + dim);
750 namebuf[namelen - 1] = ';';
752 memset(namebuf, '[', dim);
754 return class_get_classref(ref->referer,utf_new(namebuf, namelen));
757 /* class_get_classref_component_of *********************************************
759 Returns the component classref of a given array type reference
762 ref..............the array type reference
765 a reference to the component class, or
766 NULL if `ref` is not an object array type reference
769 The referer of `ref` is used as the referer for the new classref.
771 *******************************************************************************/
773 constant_classref *class_get_classref_component_of(constant_classref *ref)
780 name = ref->name->text;
784 namelen = ref->name->blength - 1;
789 else if (*name != '[') {
793 return class_get_classref(ref->referer,utf_new(name, namelen));
798 * These are local overrides for various environment variables in Emacs.
799 * Please do not remove this and leave it at the end of the file, where
800 * Emacs will automagically detect them.
801 * ---------------------------------------------------------------------
804 * indent-tabs-mode: t