X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Ftables.c;h=21437fbe09b1782f864fb163c016ff2f2bb5dd6a;hb=10d1ea93a04519d5259d534164407153008506dd;hp=48103bee3b6b5db2d5ac74854066bb4730bbe21f;hpb=b3eeed351068b34213948c0a25905c9bbcdc564a;p=cacao.git diff --git a/src/vm/tables.c b/src/vm/tables.c index 48103bee3..21437fbe0 100644 --- a/src/vm/tables.c +++ b/src/vm/tables.c @@ -1,638 +1,191 @@ -/* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */ -/****************************** tables.c *************************************** +/* src/vm/tables.c - - Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, + R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, + C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, + Institut f. Computersprachen - TU Wien - See file COPYRIGHT for information on usage and disclaimer of warranties + This file is part of CACAO. - Enth"alt Supportfunktionen f"ur: - - Lesen von JavaClass-Files - - unicode-Symbole - - den Heap - - zus"atzliche Support-Funktionen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Changes: Mark Probst EMAIL: cacao@complang.tuwien.ac.at - Andreas Krall EMAIL: cacao@complang.tuwien.ac.at + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - Last Change: 1998/03/24 + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. -*******************************************************************************/ + Contact: cacao@complang.tuwien.ac.at -#include -#include -#include -#include "global.h" -#include "tables.h" -#include "asmpart.h" -#include "callargs.h" + Authors: Reinhard Grafl -#include "threads/thread.h" /* schani */ -#include "threads/locks.h" + Changes: Mark Probst + Andreas Krall + Christian Thalinger + Contains support functions for: + - Reading of Java class files + - Unicode symbols + - the heap + - additional support functions -bool runverbose = false; + $Id: tables.c 2505 2005-05-23 08:23:40Z twisti $ -int count_unicode_len = 0; +*/ -/****************************************************************************** -************************* Der Dateien-Sauger ********************************** -******************************************************************************* - - dient zum Behandeln von Java-ClassFiles ("offnen, schlie"sen, - einlesen von 8-, 16-, 32-, 64-bit Integers und 32-, 64- bit Floats) - -******************************************************************************/ +#include +#include +#include +#include +#include +#include -static FILE *classfile = NULL; /* File-handle der gerade gelesenen Datei */ -static char *classpath = ""; /* Suchpfad f"ur die ClassFiles */ +#include "types.h" +#include "mm/memory.h" +#include "native/native.h" +#include "toolbox/logging.h" +#include "vm/builtin.h" +#include "vm/exceptions.h" +#include "vm/global.h" +#include "vm/loader.h" +#include "vm/options.h" +#include "vm/statistics.h" +#include "vm/stringlocal.h" +#include "vm/tables.h" +#include "vm/classcache.h" +hashtable string_hash; /* hashtable for javastrings */ -/************************** Funktion: suck_init ****************************** - Wird zu Programmstart einmal aufgerufen und setzt den Suchpfad f"ur - Klassenfiles +/****************************************************************************** + *********************** hashtable functions ********************************** + ******************************************************************************/ -******************************************************************************/ +/* hashsize must be power of 2 */ -void suck_init (char *cpath) -{ - classfile = NULL; - classpath = cpath; -} +#define UTF_HASHSTART 16384 /* initial size of utf-hash */ +#define HASHSTART 2048 /* initial size of javastring and class-hash */ -/************************** Funktion: suck_start ****************************** +/******************** function: init_hashtable ****************************** - "Offnet die Datei f"ur die Klasse des gegebenen Namens zum Lesen. - Dabei werden alle im Suchpfad angegebenen Verzeichnisse durchsucht, - bis eine entsprechende Datei ( .class) gefunden wird. + Initializes a hashtable structure and allocates memory. + The parameter size specifies the initial size of the hashtable. -******************************************************************************/ - -bool suck_start (unicode *classname) -{ -#define MAXFILENAME 1000 /* Maximale Langes des Dateinamens plus Pfad */ - - char filename[MAXFILENAME+10]; /* Platz fuer '.class' */ - u2 filenamelen; - char *pathpos; - u2 i,c; - - - pathpos = classpath; - - while (*pathpos) { - while ( *pathpos == ':' ) pathpos++; - - filenamelen=0; - while ( (*pathpos) && (*pathpos!=':') ) { - PANICIF (filenamelen >= MAXFILENAME, "Filename too long") ; - - filename[filenamelen++] = *(pathpos++); - } - - filename[filenamelen++] = '/'; - - for (i=0; i < classname -> length; i++) { - PANICIF (filenamelen >= MAXFILENAME, "Filename too long"); - - c = classname -> text [i]; - if (c=='/') c = '/'; /* Slashes im Namen passen zu UNIX */ - else { - if ( c<=' ' || c>'z') { - c = '?'; - } - } - - filename[filenamelen++] = c; - } - - strcpy (filename+filenamelen, ".class"); - - classfile = fopen(filename, "r"); - if (classfile) { - return true; - } - - - } - - sprintf (logtext,"Can not open class file '%s'", filename); - error(); - return false; -} - - -/************************** Funktion: suck_stop ******************************* - - Schlie"st die offene Datei wieder. - -******************************************************************************/ - -void suck_stop () -{ - u4 rest=0; - u1 dummy; - - while ( fread (&dummy, 1,1, classfile) > 0) rest++; - if (rest) { - sprintf (logtext,"There are %d access bytes at end of classfile", - (int) rest); - dolog(); - } - - fclose (classfile); - classfile = NULL; -} - - - -/************************** Lesefunktionen *********************************** - - Lesen von der Datei in verschieden grossen Paketen - (8,16,32,64-bit Integer oder Float) - *****************************************************************************/ -void suck_nbytes (u1 *buffer, u4 len) -{ - if ( fread (buffer, 1, len, classfile) != len) panic ("Unexpected EOF"); -} - - -void skip_nbytes (u4 len) +void init_hashtable(hashtable *hash, u4 size) { u4 i; - for (i=0; ientries = 0; + hash->size = size; + hash->ptr = MNEW(void*, size); - -u4 suck_u4 () -{ - u1 b[4]; - u4 v; - if ( fread (b, 1,4, classfile) != 4) panic ("Unexpected EOF"); - v = ( ((u4)b[0]) <<24) + ( ((u4)b[1])<<16) + ( ((u4)b[2])<<8) + ((u4)b[3]); - return v; + /* clear table */ + for (i = 0; i < size; i++) hash->ptr[i] = NULL; } -s4 suck_s4 () -{ - s4 v = suck_u4 (); - return v; -} -u8 suck_u8 () -{ -#if U8_AVAILABLE - u8 lo,hi; - hi = suck_u4(); - lo = suck_u4(); - return (hi<<32) + lo; -#else - u8 v; - v.high = suck_u4(); - v.low = suck_u4(); - return v; -#endif -} +/*********************** function: tables_init ***************************** -s8 suck_s8 () -{ - return suck_u8 (); -} + creates hashtables for symboltables + (called once at startup) +*****************************************************************************/ -float suck_float () +void tables_init() { - float f; - -#if !WORDS_BIGENDIAN - u1 buffer[4]; - u2 i; - for (i=0; i<4; i++) buffer[3-i] = suck_u1 (); - memcpy ( (u1*) (&f), buffer, 4); -#else - suck_nbytes ( (u1*) (&f), 4 ); -#endif + init_hashtable(&utf_hash, UTF_HASHSTART); /* hashtable for utf8-symbols */ + init_hashtable(&string_hash, HASHSTART); /* hashtable for javastrings */ - PANICIF (sizeof(float) != 4, "Incompatible float-format"); - - return f; -} + classcache_init(); +/* if (opt_eager) */ +/* list_init(&unlinkedclasses, OFFSET(classinfo, listnode)); */ -double suck_double () -{ - double d; - -#if !WORDS_BIGENDIAN - u1 buffer[8]; - u2 i; - for (i=0; i<8; i++) buffer[7-i] = suck_u1 (); - memcpy ( (u1*) (&d), buffer, 8); -#else - suck_nbytes ( (u1*) (&d), 8 ); +#if defined(STATISTICS) + if (opt_stat) + count_utf_len += sizeof(utf*) * utf_hash.size; #endif - - PANICIF (sizeof(double) != 8, "Incompatible double-format" ); - - return d; } +/********************** function: tables_close ****************************** - -/****************************************************************************** -******************** Der Unicode-Symbol-Verwalter ***************************** -******************************************************************************* - - legt eine Hashtabelle f"ur unicode-Symbole an und verwaltet - das Eintragen neuer Symbole - -******************************************************************************/ - - - -#define UNICODESTART 2187 /* Startgr"osse: moeglichst gross und prim */ - -static u4 unicodeentries; /* Anzahl der Eintr"age in der Tabelle */ -static u4 unicodehashsize; /* Gr"osse der Tabelle */ -static unicode ** unicodehash; /* Zeiger auf die Tabelle selbst */ - - -/*********************** Funktion: unicode_init ****************************** - - Initialisiert die unicode-Symboltabelle (muss zu Systemstart einmal - aufgerufen werden) + free memory for hashtables *****************************************************************************/ -void unicode_init () +void tables_close() { + utf *u = NULL; + literalstring *s; u4 i; - -#ifdef STATISTICS - count_unicode_len += sizeof(unicode*) * unicodehashsize; -#endif - - unicodeentries = 0; - unicodehashsize = UNICODESTART; - unicodehash = MNEW (unicode*, unicodehashsize); - for (i=0; ihashlink; - - if (u->string) del (u->string); - - MFREE (u->text, u2, u->length); - FREE (u, unicode); + /* process elements in external hash chain */ + utf *nextu = u->hashlink; + MFREE(u->text, u1, u->blength); + FREE(u, utf); u = nextu; - } - } - MFREE (unicodehash, unicode*, unicodehashsize); -} - - -/********************* Funktion: unicode_display ****************************** - - Gibt ein unicode-Symbol auf stdout aus (zu Debugzwecken) - -******************************************************************************/ - -void unicode_display (unicode *u) -{ - u2 i,c; - for (i=0; i < u->length; i++) { - c = u->text[i]; - if (c>=32 && c<=127) printf ("%c",c); - else printf ("?"); - } - fflush (stdout); -} - - -/********************* Funktion: unicode_sprint ****************************** - - Schreibt ein unicode-Symbol in einen C-String - -******************************************************************************/ - -void unicode_sprint (char *buffer, unicode *u) -{ - u2 i; - for (i=0; i < u->length; i++) buffer[i] = u->text[i]; - buffer[i] = '\0'; -} - - -/********************* Funktion: unicode_fprint ****************************** - - Schreibt ein unicode-Symbol auf eine Datei aus - -******************************************************************************/ - -void unicode_fprint (FILE *file, unicode *u) -{ - u2 i; - for (i=0; i < u->length; i++) putc (u->text[i], file); -} - - -/****************** interne Funktion: u_hashkey ******************************/ - -static u4 u_hashkey (u2 *text, u2 length) -{ - u4 k = 0; - u2 i,sh=0; - - for (i=0; i hashlink; - u4 slot = (u->key) % newhashsize; - - u->hashlink = newhash[slot]; - newhash[slot] = u; - - u = nextu; - } - } - - MFREE (unicodehash, unicode*, unicodehashsize); - unicodehash = newhash; - unicodehashsize = newhashsize; -} - - -/****************** Funktion: unicode_new_u2 ********************************** - - Legt ein neues unicode-Symbol an. Der Text des Symbols wird dieser - Funktion als u2-Array "ubergeben - -******************************************************************************/ - -unicode *unicode_new_u2 (u2 *text, u2 length) -{ - u4 key = u_hashkey (text, length); - u4 slot = key % unicodehashsize; - unicode *u = unicodehash[slot]; - u2 i; - - while (u) { - if (u->key == key) { - if (u->length == length) { - for (i=0; itext[i]) goto nomatch; - } - return u; - } - } - nomatch: - u = u->hashlink; - } - -#ifdef STATISTICS - count_unicode_len += sizeof(unicode) + 2 * length; -#endif - - u = NEW (unicode); - u->key = key; - u->length = length; - u->text = MNEW (u2, length); - u->class = NULL; - u->string = NULL; - u->hashlink = unicodehash[slot]; - unicodehash[slot] = u; - for (i=0; itext[i] = text[i]; - - unicodeentries++; - - if ( unicodeentries > (unicodehashsize/2)) u_reorganizehash(); - - return u; -} - - -/********************* Funktion: unicode_new_char ***************************** - - Legt ein neues unicode-Symbol an. Der Text des Symbols wird dieser - Funktion als C-String ( = char* ) "ubergeben - -******************************************************************************/ - -unicode *unicode_new_char (char *text) -{ -#define MAXNEWCHAR 500 - u2 buffer[MAXNEWCHAR]; - u2 length = 0; - u1 c; - - while ( (c = *text) != '\0' ) { - if (length>=MAXNEWCHAR) panic ("Text too long in unicode_new_char"); - buffer[length++] = c; - text ++; - } - return unicode_new_u2 (buffer, length); -} - - -/********************** Funktion: unicode_setclasslink ************************ - - H"angt einen Verweis auf eine Klasse an ein unicode-Symbol an. - -******************************************************************************/ - -void unicode_setclasslink (unicode *u, classinfo *class) -{ - PANICIF (u->class, "Attempt to attach class to already attached symbol"); - u->class = class; -} - -/********************** Funktion: unicode_getclasslink ************************ - - Sucht den Verweis von einem unicode-Symbol auf eine Klasse. - Wenn keine solche Klasse existiert, dann wird ein Fehler - ausgegeben. - -******************************************************************************/ - -classinfo *unicode_getclasslink (unicode *u) -{ - PANICIF (!u->class, "Attempt to get unknown class-reference"); - return u->class; -} - - - -/********************* Funktion: unicode_unlinkclass ************************* - - Entfernt den Verweis auf eine Klasse wieder von einem Symbol - -******************************************************************************/ - -void unicode_unlinkclass (unicode *u) -{ - PANICIF (!u->class, "Attempt to unlink not yet linked symbol"); - u -> class = NULL; -} - - - -/******************* Funktion> unicode_setstringlink ********************* - - H"angt einen Verweis auf einen konstanten String an ein - Unicode-Symbol - -*************************************************************************/ - -void unicode_setstringlink (unicode *u, java_objectheader *str) -{ - PANICIF (u->string, "Attempt to attach string to already attached symbol"); - u->string = str; -} - - -/********************* Funktion: unicode_unlinkstring ************************* - - Entfernt den Verweis auf einen String wieder von einem Symbol - -******************************************************************************/ - -void unicode_unlinkstring (unicode *u) -{ - PANICIF (!u->class, "Attempt to unlink not yet linked symbol"); - u -> string = NULL; -} - - - -/*********************** Funktion: unicode_show ****************************** - - gibt eine Aufstellung aller Symbol im unicode-hash auf stdout aus. - (nur f"ur Debug-Zwecke) - -*****************************************************************************/ - -void unicode_show () -{ - unicode *u; - u4 i; + /* process elements in external hash chain */ + literalstring *nexts = s->hashlink; + literalstring_free(s->string); + FREE(s, literalstring); + s = nexts; + } + } - printf ("UNICODE-HASH: %d slots for %d entries\n", - (int) unicodehashsize, (int) unicodeentries ); - - for (i=0; istring) printf ("(string) "); - u = u->hashlink; - } - printf ("\n"); - } - - } + /* dispose hashtable structures */ + MFREE(utf_hash.ptr, void*, utf_hash.size); + MFREE(string_hash.ptr, void*, string_hash.size); } - /****************************************************************************** -*********************** Diverse Support-Funktionen **************************** +*********************** Misc support functions ******************************** ******************************************************************************/ -/******************** Funktion: desc_to_type ********************************** - - Findet zu einem gegebenen Typdescriptor den entsprechenden - Java-Grunddatentyp. +/******************** Function: desc_to_type ********************************** + + Determines the corresponding Java base data type for a given type + descriptor. ******************************************************************************/ -u2 desc_to_type (unicode *descriptor) +u2 desc_to_type(utf *descriptor) { - if (descriptor->length < 1) panic ("Type-Descriptor is empty string"); + char *utf_ptr = descriptor->text; /* current position in utf text */ + + if (descriptor->blength < 1) { + log_text("Type-Descriptor is empty string"); + assert(0); + } - switch (descriptor->text[0]) { + switch (*utf_ptr++) { case 'B': case 'C': case 'I': @@ -645,21 +198,20 @@ u2 desc_to_type (unicode *descriptor) case '[': return TYPE_ADDRESS; } - sprintf (logtext, "Invalid Type-Descriptor: "); - unicode_sprint (logtext+strlen(logtext), descriptor); - error (); + assert(0); + return 0; } -/********************** Funktion: desc_typesize ******************************* +/********************** Function: desc_typesize ******************************* - Berechnet die L"ange (in Byte) eines Datenelements gegebenen Typs, - der durch den Typdescriptor gegeben ist. + Calculates the lenght in bytes needed for a data element of the type given + by its type descriptor. ******************************************************************************/ -u2 desc_typesize (unicode *descriptor) +u2 desc_typesize(utf *descriptor) { switch (desc_to_type(descriptor)) { case TYPE_INT: return 4; @@ -672,5 +224,15 @@ u2 desc_typesize (unicode *descriptor) } - - +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */