* classcache_lookup_name, classcache_new_name: Speed up lookup in external
[cacao.git] / src / vm / class.c
1 /* src/vm/class.c - class related functions
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Mark Probst
30             Andreas Krall
31             Christian Thalinger
32
33    $Id: class.c 3260 2005-09-21 19:41:47Z twisti $
34
35 */
36
37 #include <assert.h>
38 #include <string.h>
39
40 #include "vm/global.h"
41 #include "mm/memory.h"
42
43 #if defined(USE_THREADS)
44 # if defined(NATIVE_THREADS)
45 #  include "threads/native/threads.h"
46 # else
47 #  include "threads/green/threads.h"
48 #  include "threads/green/locks.h"
49 # endif
50 #endif
51
52 #include "toolbox/logging.h"
53 #include "vm/class.h"
54 #include "vm/classcache.h"
55 #include "vm/exceptions.h"
56 #include "vm/loader.h"
57 #include "vm/options.h"
58 #include "vm/resolve.h"
59 #include "vm/statistics.h"
60 #include "vm/tables.h"
61 #include "vm/utf8.h"
62
63
64 /******************************************************************************/
65 /* DEBUG HELPERS                                                              */
66 /******************************************************************************/
67
68 #ifndef NDEBUG
69 #define CLASS_DEBUG
70 #endif
71
72 #ifdef CLASS_DEBUG
73 #define CLASS_ASSERT(cond)  assert(cond)
74 #else
75 #define CLASS_ASSERT(cond)
76 #endif
77
78
79 /* global variables ***********************************************************/
80
81 list unlinkedclasses;                   /* this is only used for eager class  */
82                                         /* loading                            */
83
84
85 /* frequently used classes ****************************************************/
86
87 /* important system classes */
88
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_lang_ThreadGroup = NULL;
97 classinfo *class_java_io_Serializable = NULL;
98
99
100 /* system exception classes required in cacao */
101
102 classinfo *class_java_lang_Throwable = NULL;
103 classinfo *class_java_lang_VMThrowable = NULL;
104 classinfo *class_java_lang_Error = NULL;
105 classinfo *class_java_lang_NoClassDefFoundError = NULL;
106 classinfo *class_java_lang_OutOfMemoryError = NULL;
107
108 classinfo *class_java_lang_Exception = NULL;
109 classinfo *class_java_lang_ClassNotFoundException = NULL;
110
111 classinfo *class_java_lang_Void = NULL;
112 classinfo *class_java_lang_Boolean = NULL;
113 classinfo *class_java_lang_Byte = NULL;
114 classinfo *class_java_lang_Character = NULL;
115 classinfo *class_java_lang_Short = NULL;
116 classinfo *class_java_lang_Integer = NULL;
117 classinfo *class_java_lang_Long = NULL;
118 classinfo *class_java_lang_Float = NULL;
119 classinfo *class_java_lang_Double = NULL;
120
121
122 /* some classes which may be used more often */
123
124 classinfo *class_java_lang_StackTraceElement = NULL;
125 classinfo *class_java_lang_reflect_Constructor = NULL;
126 classinfo *class_java_lang_reflect_Field = NULL;
127 classinfo *class_java_lang_reflect_Method = NULL;
128 classinfo *class_java_security_PrivilegedAction = NULL;
129 classinfo *class_java_util_Vector = NULL;
130
131 classinfo *arrayclass_java_lang_Object = NULL;
132
133
134 /* pseudo classes for the typechecker */
135
136 classinfo *pseudo_class_Arraystub = NULL;
137 classinfo *pseudo_class_Null = NULL;
138 classinfo *pseudo_class_New = NULL;
139
140
141 /* class_set_packagename *******************************************************
142
143    Derive the package name from the class name and store it in the struct.
144
145 *******************************************************************************/
146
147 void class_set_packagename(classinfo *c)
148 {
149         char *p = UTF_END(c->name) - 1;
150         char *start = c->name->text;
151
152         /* set the package name */
153         /* classes in the unnamed package keep packagename == NULL */
154
155         if (c->name->text[0] == '[') {
156                 /* set packagename of arrays to the element's package */
157
158                 for (; *start == '['; start++);
159
160                 /* skip the 'L' in arrays of references */
161                 if (*start == 'L')
162                         start++;
163
164                 for (; (p > start) && (*p != '/'); --p);
165
166                 c->packagename = utf_new(start, p - start);
167
168         } else {
169                 for (; (p > start) && (*p != '/'); --p);
170
171                 c->packagename = utf_new(start, p - start);
172         }
173 }
174
175
176 /* class_create_classinfo ******************************************************
177
178    Create a new classinfo struct. The class name is set to the given utf *,
179    most other fields are initialized to zero.
180
181    Note: classname may be NULL. In this case a not-yet-named classinfo is
182          created. The name must be filled in later and class_set_packagename
183                  must be called after that.
184
185 *******************************************************************************/
186
187 classinfo *class_create_classinfo(utf *classname)
188 {
189         classinfo *c;
190
191 #if defined(STATISTICS)
192         if (opt_stat)
193                 count_class_infos += sizeof(classinfo);
194 #endif
195
196         /* we use a safe name for temporarily unnamed classes */
197         if (!classname)
198                 classname = utf_not_named_yet;
199
200         if (initverbose)
201                 log_message_utf("Creating class: ", classname);
202
203         c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
204         /*c=NEW(classinfo);*/
205         c->vmClass = 0;
206         c->flags = 0;
207         c->name = classname;
208         c->packagename = NULL;
209         c->cpcount = 0;
210         c->cptags = NULL;
211         c->cpinfos = NULL;
212         c->classrefs = NULL;
213         c->extclassrefs = NULL;
214         c->classrefcount = 0;
215         c->parseddescs = NULL;
216         c->parseddescsize = 0;
217         c->super.any = NULL;
218         c->sub = NULL;
219         c->nextsub = NULL;
220         c->interfacescount = 0;
221         c->interfaces = NULL;
222         c->fieldscount = 0;
223         c->fields = NULL;
224         c->methodscount = 0;
225         c->methods = NULL;
226         c->linked = false;
227         c->loaded = false;
228         c->index = 0;
229         c->instancesize = 0;
230         c->header.vftbl = NULL;
231         c->innerclasscount = 0;
232         c->innerclass = NULL;
233         c->vftbl = NULL;
234         c->initialized = false;
235         c->initializing = false;
236         c->classvftbl = false;
237     c->classUsed = 0;
238     c->impldBy = NULL;
239         c->classloader = NULL;
240         c->sourcefile = NULL;
241         
242         if (classname != utf_not_named_yet) {
243                 class_set_packagename(c);
244         }
245
246 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
247         initObjectLock(&c->header);
248 #endif
249
250         return c;
251 }
252
253 /* class_freepool **************************************************************
254
255         Frees all resources used by this classes Constant Pool.
256
257 *******************************************************************************/
258
259 static void class_freecpool(classinfo *c)
260 {
261         u4 idx;
262         u4 tag;
263         voidptr info;
264         
265         if (c->cptags && c->cpinfos) {
266                 for (idx = 0; idx < c->cpcount; idx++) {
267                         tag = c->cptags[idx];
268                         info = c->cpinfos[idx];
269                 
270                         if (info != NULL) {
271                                 switch (tag) {
272                                 case CONSTANT_Fieldref:
273                                 case CONSTANT_Methodref:
274                                 case CONSTANT_InterfaceMethodref:
275                                         FREE(info, constant_FMIref);
276                                         break;
277                                 case CONSTANT_Integer:
278                                         FREE(info, constant_integer);
279                                         break;
280                                 case CONSTANT_Float:
281                                         FREE(info, constant_float);
282                                         break;
283                                 case CONSTANT_Long:
284                                         FREE(info, constant_long);
285                                         break;
286                                 case CONSTANT_Double:
287                                         FREE(info, constant_double);
288                                         break;
289                                 case CONSTANT_NameAndType:
290                                         FREE(info, constant_nameandtype);
291                                         break;
292                                 }
293                         }
294                 }
295         }
296
297         if (c->cptags)
298                 MFREE(c->cptags, u1, c->cpcount);
299
300         if (c->cpinfos)
301                 MFREE(c->cpinfos, voidptr, c->cpcount);
302 }
303
304
305 /* class_getconstant ***********************************************************
306
307    Retrieves the value at position 'pos' of the constantpool of a
308    class. If the type of the value is other than 'ctype', an error is
309    thrown.
310
311 *******************************************************************************/
312
313 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
314 {
315         /* check index and type of constantpool entry */
316         /* (pos == 0 is caught by type comparison) */
317
318         if (pos >= c->cpcount || c->cptags[pos] != ctype) {
319                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
320                 return NULL;
321         }
322
323         return c->cpinfos[pos];
324 }
325
326
327 /* innerclass_getconstant ******************************************************
328
329    Like class_getconstant, but if cptags is ZERO, null is returned.
330         
331 *******************************************************************************/
332
333 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
334 {
335         /* invalid position in constantpool */
336         if (pos >= c->cpcount) {
337                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
338                 return NULL;
339         }
340
341         /* constantpool entry of type 0 */      
342         if (!c->cptags[pos])
343                 return NULL;
344
345         /* check type of constantpool entry */
346         if (c->cptags[pos] != ctype) {
347                 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
348                 return NULL;
349         }
350                 
351         return c->cpinfos[pos];
352 }
353
354
355 /* class_free ******************************************************************
356
357    Frees all resources used by the class.
358
359 *******************************************************************************/
360
361 void class_free(classinfo *c)
362 {
363         s4 i;
364         vftbl_t *v;
365                 
366         class_freecpool(c);
367
368         if (c->interfaces)
369                 MFREE(c->interfaces, classinfo*, c->interfacescount);
370
371         if (c->fields) {
372                 for (i = 0; i < c->fieldscount; i++)
373                         field_free(&(c->fields[i]));
374 /*      MFREE(c->fields, fieldinfo, c->fieldscount); */
375         }
376         
377         if (c->methods) {
378                 for (i = 0; i < c->methodscount; i++)
379                         method_free(&(c->methods[i]));
380                 MFREE(c->methods, methodinfo, c->methodscount);
381         }
382
383         if ((v = c->vftbl) != NULL) {
384                 if (v->arraydesc)
385                         mem_free(v->arraydesc,sizeof(arraydescriptor));
386                 
387                 for (i = 0; i < v->interfacetablelength; i++) {
388                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
389                 }
390                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
391
392                 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
393                     sizeof(methodptr*) * (v->interfacetablelength -
394                                          (v->interfacetablelength > 0));
395                 v = (vftbl_t*) (((methodptr*) v) -
396                                                 (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
397                 mem_free(v, i);
398         }
399
400         if (c->innerclass)
401                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
402
403         /*      if (c->classvftbl)
404                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
405         
406 /*      GCFREE(c); */
407 }
408
409
410 /* get_array_class *************************************************************
411
412    Returns the array class with the given name for the given
413    classloader, or NULL if an exception occurred.
414
415    Note: This function does eager loading. 
416
417 *******************************************************************************/
418
419 static classinfo *get_array_class(utf *name,java_objectheader *initloader,
420                                                                                         java_objectheader *defloader,bool link)
421 {
422         classinfo *c;
423         
424         /* lookup this class in the classcache */
425         c = classcache_lookup(initloader,name);
426         if (!c)
427                 c = classcache_lookup_defined(defloader,name);
428
429         if (!c) {
430                 /* we have to create it */
431                 c = class_create_classinfo(name);
432                 c = load_newly_created_array(c,initloader);
433                 if (c == NULL)
434                         return NULL;
435         }
436
437         CLASS_ASSERT(c);
438         CLASS_ASSERT(c->loaded);
439         CLASS_ASSERT(c->classloader == defloader);
440
441         if (link && !c->linked)
442                 if (!link_class(c))
443                         return NULL;
444
445         CLASS_ASSERT(!link || c->linked);
446
447         return c;
448 }
449
450
451 /* class_array_of **************************************************************
452
453    Returns an array class with the given component class. The array
454    class is dynamically created if neccessary.
455
456 *******************************************************************************/
457
458 classinfo *class_array_of(classinfo *component, bool link)
459 {
460     s4 namelen;
461     char *namebuf;
462
463     /* Assemble the array class name */
464     namelen = component->name->blength;
465     
466     if (component->name->text[0] == '[') {
467         /* the component is itself an array */
468         namebuf = DMNEW(char, namelen + 1);
469         namebuf[0] = '[';
470         MCOPY(namebuf + 1, component->name->text, char, namelen);
471         namelen++;
472
473     } else {
474         /* the component is a non-array class */
475         namebuf = DMNEW(char, namelen + 3);
476         namebuf[0] = '[';
477         namebuf[1] = 'L';
478         MCOPY(namebuf + 2, component->name->text, char, namelen);
479         namebuf[2 + namelen] = ';';
480         namelen += 3;
481     }
482
483         return get_array_class(utf_new(namebuf, namelen),
484                                                    component->classloader,
485                                                    component->classloader,
486                                                    link);
487 }
488
489
490 /* class_multiarray_of *********************************************************
491
492    Returns an array class with the given dimension and element class.
493    The array class is dynamically created if neccessary.
494
495 *******************************************************************************/
496
497 classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
498 {
499     s4 namelen;
500     char *namebuf;
501
502         if (dim < 1) {
503                 log_text("Invalid array dimension requested");
504                 assert(0);
505         }
506
507     /* Assemble the array class name */
508     namelen = element->name->blength;
509     
510     if (element->name->text[0] == '[') {
511         /* the element is itself an array */
512         namebuf = DMNEW(char, namelen + dim);
513         memcpy(namebuf + dim, element->name->text, namelen);
514         namelen += dim;
515     }
516     else {
517         /* the element is a non-array class */
518         namebuf = DMNEW(char, namelen + 2 + dim);
519         namebuf[dim] = 'L';
520         memcpy(namebuf + dim + 1, element->name->text, namelen);
521         namelen += (2 + dim);
522         namebuf[namelen - 1] = ';';
523     }
524         memset(namebuf, '[', dim);
525
526         return get_array_class(utf_new(namebuf, namelen),
527                                                    element->classloader,
528                                                    element->classloader,
529                                                    link);
530 }
531
532
533 /* class_lookup_classref *******************************************************
534
535    Looks up the constant_classref for a given classname in the classref
536    tables of a class.
537
538    IN:
539        cls..............the class containing the reference
540            name.............the name of the class refered to
541
542     RETURN VALUE:
543            a pointer to a constant_classref, or 
544            NULL if the reference was not found
545    
546 *******************************************************************************/
547
548 constant_classref *class_lookup_classref(classinfo *cls, utf *name)
549 {
550         constant_classref *ref;
551         extra_classref *xref;
552         int count;
553
554         CLASS_ASSERT(cls);
555         CLASS_ASSERT(name);
556         CLASS_ASSERT(!cls->classrefcount || cls->classrefs);
557         
558         /* first search the main classref table */
559         count = cls->classrefcount;
560         ref = cls->classrefs;
561         for (; count; --count, ++ref)
562                 if (ref->name == name)
563                         return ref;
564
565         /* next try the list of extra classrefs */
566         for (xref = cls->extclassrefs; xref; xref = xref->next) {
567                 if (xref->classref.name == name)
568                         return &(xref->classref);
569         }
570
571         /* not found */
572         return NULL;
573 }
574
575
576 /* class_get_classref **********************************************************
577
578    Returns the constant_classref for a given classname.
579
580    IN:
581        cls..............the class containing the reference
582            name.............the name of the class refered to
583
584    RETURN VALUE:
585        a pointer to a constant_classref (never NULL)
586
587    NOTE:
588        The given name is not checked for validity!
589    
590 *******************************************************************************/
591
592 constant_classref *class_get_classref(classinfo *cls, utf *name)
593 {
594         constant_classref *ref;
595         extra_classref *xref;
596
597         CLASS_ASSERT(cls);
598         CLASS_ASSERT(name);
599
600         ref = class_lookup_classref(cls,name);
601         if (ref)
602                 return ref;
603
604         xref = NEW(extra_classref);
605         CLASSREF_INIT(xref->classref,cls,name);
606
607         xref->next = cls->extclassrefs;
608         cls->extclassrefs = xref;
609
610         return &(xref->classref);
611 }
612
613
614 /* class_get_self_classref *****************************************************
615
616    Returns the constant_classref to the class itself.
617
618    IN:
619        cls..............the class containing the reference
620
621    RETURN VALUE:
622        a pointer to a constant_classref (never NULL)
623
624 *******************************************************************************/
625
626 constant_classref *class_get_self_classref(classinfo *cls)
627 {
628         /* XXX this should be done in a faster way. Maybe always make */
629         /* the classref of index 0 a self reference.                  */
630         return class_get_classref(cls,cls->name);
631 }
632
633 /* class_get_classref_multiarray_of ********************************************
634
635    Returns an array type reference with the given dimension and element class
636    reference.
637
638    IN:
639        dim..............the requested dimension
640                             dim must be in [1;255]. This is NOT checked!
641            ref..............the component class reference
642
643    RETURN VALUE:
644        a pointer to the class reference for the array type
645
646    NOTE:
647        The referer of `ref` is used as the referer for the new classref.
648
649 *******************************************************************************/
650
651 constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
652 {
653     s4 namelen;
654     char *namebuf;
655
656         CLASS_ASSERT(ref);
657         CLASS_ASSERT(dim >= 1 && dim <= 255);
658
659     /* Assemble the array class name */
660     namelen = ref->name->blength;
661     
662     if (ref->name->text[0] == '[') {
663         /* the element is itself an array */
664         namebuf = DMNEW(char, namelen + dim);
665         memcpy(namebuf + dim, ref->name->text, namelen);
666         namelen += dim;
667     }
668     else {
669         /* the element is a non-array class */
670         namebuf = DMNEW(char, namelen + 2 + dim);
671         namebuf[dim] = 'L';
672         memcpy(namebuf + dim + 1, ref->name->text, namelen);
673         namelen += (2 + dim);
674         namebuf[namelen - 1] = ';';
675     }
676         memset(namebuf, '[', dim);
677
678     return class_get_classref(ref->referer,utf_new(namebuf, namelen));
679 }
680
681 /* class_get_classref_component_of *********************************************
682
683    Returns the component classref of a given array type reference
684
685    IN:
686        ref..............the array type reference
687
688    RETURN VALUE:
689        a reference to the component class, or
690            NULL if `ref` is not an object array type reference
691
692    NOTE:
693        The referer of `ref` is used as the referer for the new classref.
694
695 *******************************************************************************/
696
697 constant_classref *class_get_classref_component_of(constant_classref *ref)
698 {
699         s4 namelen;
700         char *name;
701         
702         CLASS_ASSERT(ref);
703
704         name = ref->name->text;
705         if (*name++ != '[')
706                 return NULL;
707         
708         namelen = ref->name->blength - 1;
709         if (*name == 'L') {
710                 name++;
711                 namelen -= 2;
712         }
713         else if (*name != '[') {
714                 return NULL;
715         }
716
717     return class_get_classref(ref->referer, utf_new(name, namelen));
718 }
719
720
721 /*
722  * These are local overrides for various environment variables in Emacs.
723  * Please do not remove this and leave it at the end of the file, where
724  * Emacs will automagically detect them.
725  * ---------------------------------------------------------------------
726  * Local variables:
727  * mode: c
728  * indent-tabs-mode: t
729  * c-basic-offset: 4
730  * tab-width: 4
731  * End:
732  */