X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fstring.c;h=7932edcae7746e31626291cd55d181b945cc3d10;hb=1877fd859ce66e28d7142b968168c54067262d5c;hp=6e3ddb90fb1ad343abbd94347c8b5d3446da4730;hpb=408b2f1451e5ebdc65366e2ea05eb97826dabb76;p=cacao.git diff --git a/src/vm/string.c b/src/vm/string.c index 6e3ddb90f..7932edcae 100644 --- a/src/vm/string.c +++ b/src/vm/string.c @@ -30,7 +30,7 @@ Changes: Christian Thalinger - $Id: string.c 2663 2005-06-13 14:20:15Z twisti $ + $Id: string.c 4126 2006-01-10 20:55:41Z twisti $ */ @@ -38,7 +38,7 @@ #include #include "config.h" -#include "types.h" +#include "vm/types.h" #include "vm/global.h" @@ -51,6 +51,19 @@ #include "vm/utf8.h" +/* global variables ***********************************************************/ + +/* hashsize must be power of 2 */ + +#define HASHTABLE_STRING_SIZE 2048 /* initial size of javastring-hash */ + +hashtable hashtable_string; /* hashtable for javastrings */ + +#if defined(USE_THREADS) +static java_objectheader *lock_hashtable_string; +#endif + + /* global string definitions **************************************************/ /* exception/error super class */ @@ -142,6 +155,9 @@ const char *string_java_lang_ExceptionInInitializerError = const char *string_java_lang_IncompatibleClassChangeError = "java/lang/IncompatibleClassChangeError"; +const char *string_java_lang_InstantiationError = + "java/lang/InstantiationError"; + const char *string_java_lang_InternalError = "java/lang/InternalError"; @@ -173,6 +189,34 @@ const char *string_java_lang_VirtualMachineError = "java/lang/VirtualMachineError"; +/* string_init ***************************************************************** + + Initialize the string hashtable lock. + +*******************************************************************************/ + +bool string_init(void) +{ + /* create string (javastring) hashtable */ + + hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE); + +#if defined(USE_THREADS) + /* create string hashtable lock object */ + + lock_hashtable_string = NEW(java_objectheader); + +# if defined(NATIVE_THREADS) + initObjectLock(lock_hashtable_string); +# endif +#endif + + /* everything's ok */ + + return true; +} + + /* stringtable_update ********************************************************** Traverses the javastring hashtable and sets the vftbl-entries of @@ -188,8 +232,8 @@ void stringtable_update(void) literalstring *s; /* hashtable entry */ int i; - for (i = 0; i < string_hash.size; i++) { - s = string_hash.ptr[i]; + for (i = 0; i < hashtable_string.size; i++) { + s = hashtable_string.ptr[i]; if (s) { while (s) { @@ -237,7 +281,7 @@ java_lang_String *javastring_new(utf *u) s4 i; if (!u) { - *exceptionptr = new_nullpointerexception(); + exceptions_throw_nullpointerexception(); return NULL; } @@ -282,7 +326,7 @@ java_lang_String *javastring_new_slash_to_dot(utf *u) u2 ch; if (!u) { - *exceptionptr = new_nullpointerexception(); + exceptions_throw_nullpointerexception(); return NULL; } @@ -330,7 +374,7 @@ java_lang_String *javastring_new_char(const char *text) java_chararray *a; if (!text) { - *exceptionptr = new_nullpointerexception(); + exceptions_throw_nullpointerexception(); return NULL; } @@ -412,10 +456,8 @@ utf *javastring_toutf(java_lang_String *string, bool isclassname) *******************************************************************************/ -s4 javastring_strlen(java_objectheader *so) +s4 javastring_strlen(java_lang_String *s) { - java_lang_String *s = (java_lang_String *) so; - if (!s) return 0; @@ -435,32 +477,42 @@ s4 javastring_strlen(java_objectheader *so) java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, bool copymode) { - literalstring *s; /* hashtable element */ - java_lang_String *js; /* u2-array wrapped in javastring */ - java_chararray *stringdata; /* copy of u2-array */ - u4 key; - u4 slot; - u2 i; + literalstring *s; /* hashtable element */ + java_lang_String *js; /* u2-array wrapped in javastring */ + java_chararray *stringdata; /* copy of u2-array */ + u4 key; + u4 slot; + u2 i; + +#if defined(USE_THREADS) + builtin_monitorenter(lock_hashtable_string); +#endif /* find location in hashtable */ + key = unicode_hashkey(a->data + offset, length); - slot = key & (string_hash.size - 1); - s = string_hash.ptr[slot]; + slot = key & (hashtable_string.size - 1); + s = hashtable_string.ptr[slot]; while (s) { js = (java_lang_String *) s->string; if (length == js->count) { /* compare text */ - for (i = 0; i < length; i++) { + + for (i = 0; i < length; i++) if (a->data[offset + i] != js->value->data[i]) goto nomatch; - } /* string already in hashtable, free memory */ + if (!copymode) mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10); +#if defined(USE_THREADS) + builtin_monitorexit(lock_hashtable_string); +#endif + return (java_objectheader *) js; } @@ -492,7 +544,7 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, class_java_lang_String = load_class_bootstrap(utf_java_lang_String); assert(class_java_lang_String); - assert(class_java_lang_String->loaded); + assert(class_java_lang_String->state & CLASS_LOADED); /* if we use eager loading, we have to check loaded String class */ @@ -502,57 +554,72 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, /* create new javastring */ js = NEW(java_lang_String); + #if defined(USE_THREADS) && defined(NATIVE_THREADS) initObjectLock(&js->header); #endif + js->header.vftbl = class_java_lang_String->vftbl; js->value = stringdata; js->offset = 0; js->count = length; /* create new literalstring */ + s = NEW(literalstring); - s->hashlink = string_hash.ptr[slot]; + s->hashlink = hashtable_string.ptr[slot]; s->string = (java_objectheader *) js; - string_hash.ptr[slot] = s; + hashtable_string.ptr[slot] = s; /* update number of hashtable entries */ - string_hash.entries++; + + hashtable_string.entries++; /* reorganization of hashtable */ - if (string_hash.entries > (string_hash.size * 2)) { - /* reorganization of hashtable, average length of - the external chains is approx. 2 */ - u4 i; - literalstring *s; - hashtable newhash; /* the new hashtable */ + if (hashtable_string.entries > (hashtable_string.size * 2)) { + /* reorganization of hashtable, average length of the external + chains is approx. 2 */ + + u4 i; + literalstring *s; + literalstring *nexts; + java_lang_String *tmpjs; + hashtable newhash; /* the new hashtable */ /* create new hashtable, double the size */ - init_hashtable(&newhash, string_hash.size * 2); - newhash.entries = string_hash.entries; + + hashtable_create(&newhash, hashtable_string.size * 2); + newhash.entries = hashtable_string.entries; /* transfer elements to new hashtable */ - for (i = 0; i < string_hash.size; i++) { - s = string_hash.ptr[i]; + + for (i = 0; i < hashtable_string.size; i++) { + s = hashtable_string.ptr[i]; + while (s) { - literalstring *nexts = s->hashlink; - js = (java_lang_String *) s->string; - slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1); + nexts = s->hashlink; + tmpjs = (java_lang_String *) s->string; + slot = unicode_hashkey(tmpjs->value->data, tmpjs->count) & (newhash.size - 1); s->hashlink = newhash.ptr[slot]; newhash.ptr[slot] = s; - /* follow link in external hash chain */ + /* follow link in external hash chain */ s = nexts; } } - /* dispose old table */ - MFREE(string_hash.ptr, void*, string_hash.size); - string_hash = newhash; + /* dispose old table */ + + MFREE(hashtable_string.ptr, void*, hashtable_string.size); + hashtable_string = newhash; } +#if defined(USE_THREADS) + builtin_monitorexit(lock_hashtable_string); +#endif + return (java_objectheader *) js; } @@ -566,11 +633,11 @@ java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, java_objectheader *literalstring_new(utf *u) { - char *utf_ptr; /* pointer to current unicode character */ + char *utf_ptr; /* pointer to current unicode character */ /* utf string */ - u4 utflength; /* length of utf-string if uncompressed */ + u4 utflength; /* length of utf-string if uncompressed */ java_chararray *a; /* u2-array constructed from utf string */ - u4 i; + u4 i; utf_ptr = u->text; utflength = utf_strlen(u);