X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Ftables.c;h=40b880e64371dd7fc0289f8c9bc19c7bc1d8e9cd;hb=4f021ace4cbb48cb8d75e5445929a01f61ca756a;hp=d0af568c954a9fb23f0aaa08a75dd04dd6a449ad;hpb=8ea2beae60a5ea6f0e3b2bedfa030d4a7c4ac394;p=cacao.git diff --git a/src/vm/tables.c b/src/vm/tables.c index d0af568c9..40b880e64 100644 --- a/src/vm/tables.c +++ b/src/vm/tables.c @@ -1,45 +1,72 @@ -/* -*- 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. - Contains support functions for: - - Reading of Java class files - - Unicode symbols - - the heap - - additional support functions + 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 - - Last Change: 1998/03/24 + 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. -*******************************************************************************/ + 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 + + Authors: Reinhard Grafl + + Changes: Mark Probst + Andreas Krall + Christian Thalinger + + Contains support functions for: + - Reading of Java class files + - Unicode symbols + - the heap + - additional support functions + + $Id: tables.c 3679 2005-11-16 12:12:02Z twisti $ + +*/ + +#include +#include #include +#include #include #include -#include "global.h" -#include "tables.h" -#include "asmpart.h" -#include "callargs.h" -#include "threads/thread.h" /* schani */ -#include "threads/locks.h" +#include "config.h" +#include "vm/types.h" -bool runverbose = false; +#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" -/* statistics */ -int count_utf_len = 0; /* size of utf hash */ -int count_utf_new = 0; /* calls of utf_new */ -int count_utf_new_found = 0; /* calls of utf_new with fast return */ -hashtable utf_hash; /* hashtable for utf8-symbols */ hashtable string_hash; /* hashtable for javastrings */ -hashtable class_hash; /* hashtable for classes */ + /****************************************************************************** *********************** hashtable functions ********************************** @@ -64,448 +91,81 @@ void init_hashtable(hashtable *hash, u4 size) hash->entries = 0; hash->size = size; - hash->ptr = MNEW (void*, size); + hash->ptr = MNEW(void*, size); /* clear table */ - for (i=0; iptr[i] = NULL; + for (i = 0; i < size; i++) hash->ptr[i] = NULL; } -/*********************** function: tables_init ***************************** - creates hashtables for symboltables - (called once at startup) +/* tables_init ***************************************************************** + + Creates hashtables for symboltables (called once at startup). -*****************************************************************************/ +*******************************************************************************/ -void tables_init () +bool tables_init(void) { init_hashtable(&utf_hash, UTF_HASHSTART); /* hashtable for utf8-symbols */ init_hashtable(&string_hash, HASHSTART); /* hashtable for javastrings */ - init_hashtable(&class_hash, HASHSTART); /* hashtable for classes */ - -#ifdef STATISTICS - count_utf_len += sizeof(utf*) * utf_hash.size; + +/* if (opt_eager) */ +/* list_init(&unlinkedclasses, OFFSET(classinfo, listnode)); */ + +#if defined(STATISTICS) + if (opt_stat) + count_utf_len += sizeof(utf*) * utf_hash.size; #endif + /* everything's ok */ + + return true; } + /********************** function: tables_close ****************************** free memory for hashtables *****************************************************************************/ -void tables_close (stringdeleter del) +void tables_close() { - utf *u; + utf *u = NULL; literalstring *s; u4 i; + + classcache_free(); /* dispose utf symbols */ - for (i=0; ihashlink; - MFREE (u->text, u1, u->blength); - FREE (u, utf); + MFREE(u->text, u1, u->blength); + FREE(u, utf); u = nextu; - } - } + } + } /* dispose javastrings */ - for (i=0; ihashlink; - del(s->string); + literalstring_free(s->string); FREE(s, literalstring); s = nexts; - } - } - - /* dispose hashtable structures */ - MFREE (utf_hash.ptr, void*, utf_hash.size); - MFREE (string_hash.ptr, void*, string_hash.size); - MFREE (class_hash.ptr, void*, class_hash.size); -} - -/********************* function: utf_display ********************************* - - write utf symbol to stdout (debugging purposes) - -******************************************************************************/ - -void utf_display (utf *u) -{ - char *endpos = utf_end(u); /* points behind utf string */ - char *utf_ptr = u->text; /* current position in utf text */ - - while (utf_ptr=32 && c<=127) printf ("%c",c); - else printf ("?"); - } - - fflush (stdout); -} - -/************************ function: utf_sprint ******************************* - - write utf symbol into c-string (debugging purposes) - -******************************************************************************/ - -void utf_sprint (char *buffer, utf *u) -{ - char *endpos = utf_end(u); /* points behind utf string */ - char *utf_ptr = u->text; /* current position in utf text */ - u2 pos = 0; /* position in c-string */ - - while (utf_ptrtext; /* current position in utf text */ - - while (utf_ptrblength == length) { - - /* compare text of hashtable elements */ - for (i=0; itext[i]) goto nomatch; - -#ifdef STATISTICS - count_utf_new_found++; -#endif - /* symbol found in hashtable */ - return u; - } - nomatch: - u = u->hashlink; /* next element in external chain */ + } } -#ifdef STATISTICS - count_utf_len += sizeof(utf) + length; -#endif - - /* location in hashtable found, create new utf element */ - u = NEW (utf); - u->blength = length; /* length in bytes of utfstring */ - u->hashlink = utf_hash.ptr[slot]; /* link in external hashchain */ - u->text = mem_alloc(length); /* allocate memory for utf-text */ - memcpy(u->text,text,length); /* copy utf-text */ - utf_hash.ptr[slot] = u; /* insert symbol into table */ - - utf_hash.entries++; /* update number of entries */ - - if ( utf_hash.entries > (utf_hash.size*2)) { - - /* reorganization of hashtable, average length of - the external chains is approx. 2 */ - - u4 i; - utf *u; - hashtable newhash; /* the new hashtable */ - - /* create new hashtable, double the size */ - init_hashtable(&newhash, utf_hash.size*2); - newhash.entries=utf_hash.entries; - -#ifdef STATISTICS - count_utf_len += sizeof(utf*) * utf_hash.size; -#endif - - /* transfer elements to new hashtable */ - for (i=0; i hashlink; - u4 slot = (utf_hashkey(u->text,u->blength)) & (newhash.size-1); - - u->hashlink = (utf*) newhash.ptr[slot]; - newhash.ptr[slot] = u; - - /* follow link in external hash chain */ - u = nextu; - } - } - - /* dispose old table */ - MFREE (utf_hash.ptr, void*, utf_hash.size); - utf_hash = newhash; - } - - return u; -} - - -/********************* function: utf_new_char ******************************** - - creates a new utf symbol, the text for this symbol is passed - as a c-string ( = char* ) - -******************************************************************************/ - -utf *utf_new_char (char *text) -{ - return utf_new(text, strlen(text)); + /* dispose hashtable structures */ + MFREE(utf_hash.ptr, void*, utf_hash.size); + MFREE(string_hash.ptr, void*, string_hash.size); } -/************************** Funktion: utf_show ****************************** - - writes the utf symbols in the utfhash to stdout and - displays the number of external hash chains grouped - according to the chainlength - (debugging purposes) - -*****************************************************************************/ - -void utf_show () -{ - -#define CHAIN_LIMIT 20 /* limit for seperated enumeration */ - - u4 chain_count[CHAIN_LIMIT]; /* numbers of chains */ - u4 max_chainlength = 0; /* maximum length of the chains */ - u4 sum_chainlength = 0; /* sum of the chainlengths */ - u4 beyond_limit = 0; /* number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */ - u4 i; - - printf ("UTF-HASH:\n"); - - /* show element of utf-hashtable */ - for (i=0; ihashlink; - } - printf ("\n"); - } - - } - - printf ("UTF-HASH: %d slots for %d entries\n", - (int) utf_hash.size, (int) utf_hash.entries ); - - - if (utf_hash.entries == 0) - return; - - printf("chains:\n chainlength number of chains %% of utfstrings\n"); - - for (i=0;ihashlink; - chain_length++; - } - - /* update sum of all chainlengths */ - sum_chainlength+=chain_length; - - /* determine the maximum length of the chains */ - if (chain_length>max_chainlength) - max_chainlength = chain_length; - - /* update number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */ - if (chain_length>=CHAIN_LIMIT) { - beyond_limit+=chain_length; - chain_length=CHAIN_LIMIT-1; - } - - /* update number of hashchains of current length */ - chain_count[chain_length]++; - } - - /* display results */ - for (i=1;i=%2d %17d %18.2f%%\n",CHAIN_LIMIT-1,chain_count[CHAIN_LIMIT-1],((float) beyond_limit*100)/utf_hash.entries); - - - printf("max. chainlength:%5d\n",max_chainlength); - - /* avg. chainlength = sum of chainlengths / number of chains */ - printf("avg. chainlength:%5.2f\n",(float) sum_chainlength / (utf_hash.size-chain_count[0])); -} /****************************************************************************** *********************** Misc support functions ******************************** @@ -519,11 +179,14 @@ void utf_show () ******************************************************************************/ -u2 desc_to_type (utf *descriptor) +u2 desc_to_type(utf *descriptor) { char *utf_ptr = descriptor->text; /* current position in utf text */ - if (descriptor->blength < 1) panic ("Type-Descriptor is empty string"); + if (descriptor->blength < 1) { + log_text("Type-Descriptor is empty string"); + assert(0); + } switch (*utf_ptr++) { case 'B': @@ -538,9 +201,8 @@ u2 desc_to_type (utf *descriptor) case '[': return TYPE_ADDRESS; } - sprintf (logtext, "Invalid Type-Descriptor: "); - utf_sprint (logtext+strlen(logtext), descriptor); - error (); + assert(0); + return 0; } @@ -552,7 +214,7 @@ u2 desc_to_type (utf *descriptor) ******************************************************************************/ -u2 desc_typesize (utf *descriptor) +u2 desc_typesize(utf *descriptor) { switch (desc_to_type(descriptor)) { case TYPE_INT: return 4; @@ -565,252 +227,15 @@ u2 desc_typesize (utf *descriptor) } -/********************** function: utf_nextu2 ********************************* - - read the next unicode character from the utf string and - increment the utf-string pointer accordingly - -******************************************************************************/ - -u2 utf_nextu2(char **utf_ptr) -{ - /* uncompressed unicode character */ - u2 unicode_char; - /* current position in utf text */ - unsigned char *utf = (unsigned char *) (*utf_ptr); - /* bytes representing the unicode character */ - unsigned char ch1, ch2, ch3; - /* number of bytes used to represent the unicode character */ - int len; - - switch ((ch1 = utf[0]) >> 4) { - default: /* 1 byte */ - (*utf_ptr)++; - return ch1; - case 0xC: - case 0xD: /* 2 bytes */ - if (((ch2 = utf[1]) & 0xC0) == 0x80) { - unsigned char high = ch1 & 0x1F; - unsigned char low = ch2 & 0x3F; - unicode_char = (high << 6) + low; - len = 2; - } - break; - - case 0xE: /* 2 or 3 bytes */ - if (((ch2 = utf[1]) & 0xC0) == 0x80) { - if (((ch3 = utf[2]) & 0xC0) == 0x80) { - unsigned char low = ch3 & 0x3f; - unsigned char mid = ch2 & 0x3f; - unsigned char high = ch1 & 0x0f; - unicode_char = (((high << 6) + mid) << 6) + low; - len = 3; - } else - len = 2; - } - break; - } - - /* update position in utf-text */ - *utf_ptr = (char *) (utf + len); - return unicode_char; -} - -/******************** Function: class_new ************************************** - - searches for the class with the specified name in the classes hashtable, - if there is no such class a new classinfo structure is created and inserted - into the list of classes to be loaded - -*******************************************************************************/ - -classinfo *class_new (utf *u) -{ - classinfo *c; /* hashtable element */ - u4 key; /* hashkey computed from classname */ - u4 slot; /* slot in hashtable */ - u2 i; - - key = utf_hashkey (u->text, u->blength); - slot = key & (class_hash.size-1); - c = class_hash.ptr[slot]; - - /* search external hash chain for the class */ - while (c) { - if (c->name->blength == u->blength) { - for (i=0; iblength; i++) - if (u->text[i] != c->name->text[i]) goto nomatch; - - /* class found in hashtable */ - return c; - } - - nomatch: - c = c->hashlink; /* next element in external chain */ - } - - /* location in hashtable found, create new classinfo structure */ - -#ifdef STATISTICS - count_class_infos += sizeof(classinfo); -#endif - - c = NEW (classinfo); - c -> flags = 0; - c -> name = u; - c -> cpcount = 0; - c -> cptags = NULL; - c -> cpinfos = NULL; - c -> super = NULL; - c -> sub = NULL; - c -> nextsub = NULL; - c -> interfacescount = 0; - c -> interfaces = NULL; - c -> fieldscount = 0; - c -> fields = NULL; - c -> methodscount = 0; - c -> methods = NULL; - c -> linked = false; - c -> index = 0; - c -> instancesize = 0; - c -> header.vftbl = NULL; - c -> innerclasscount = 0; - c -> innerclass = NULL; - c -> vftbl = NULL; - c -> initialized = false; - c -> classvftbl = false; - - /* prepare loading of the class */ - list_addlast (&unloadedclasses, c); - - /* insert class into the hashtable */ - c->hashlink = class_hash.ptr[slot]; - class_hash.ptr[slot] = c; - - /* update number of hashtable-entries */ - class_hash.entries++; - - if ( class_hash.entries > (class_hash.size*2)) { - - /* reorganization of hashtable, average length of - the external chains is approx. 2 */ - - u4 i; - classinfo *c; - hashtable newhash; /* the new hashtable */ - - /* create new hashtable, double the size */ - init_hashtable(&newhash, class_hash.size*2); - newhash.entries = class_hash.entries; - - /* transfer elements to new hashtable */ - for (i=0; i hashlink; - u4 slot = (utf_hashkey(c->name->text,c->name->blength)) & (newhash.size-1); - - c->hashlink = newhash.ptr[slot]; - newhash.ptr[slot] = c; - - c = nextc; - } - } - - /* dispose old table */ - MFREE (class_hash.ptr, void*, class_hash.size); - class_hash = newhash; - } - - return c; -} - -/******************** Function: class_get ************************************** - - searches for the class with the specified name in the classes hashtable - if there is no such class NULL is returned - -*******************************************************************************/ - -classinfo *class_get (utf *u) -{ - classinfo *c; /* hashtable element */ - u4 key; /* hashkey computed from classname */ - u4 slot; /* slot in hashtable */ - u2 i; - - key = utf_hashkey (u->text, u->blength); - slot = key & (class_hash.size-1); - c = class_hash.ptr[slot]; - - /* search external hash-chain */ - while (c) { - if (c->name->blength == u->blength) { - - /* compare classnames */ - for (i=0; iblength; i++) - if (u->text[i] != c->name->text[i]) goto nomatch; - - /* class found in hashtable */ - return c; - } - - nomatch: - c = c->hashlink; - } - - /* class not found */ - return NULL; -} - - -/************************** function: utf_strlen ****************************** - - determine number of unicode characters in the utf string - -*******************************************************************************/ - -u4 utf_strlen(utf *u) -{ - char *endpos = utf_end(u); /* points behind utf string */ - char *utf_ptr = u->text; /* current position in utf text */ - u4 len = 0; /* number of unicode characters */ - - while (utf_ptr