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 $
*/
#include <assert.h>
#include "config.h"
-#include "types.h"
+#include "vm/types.h"
#include "vm/global.h"
#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 */
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";
"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
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) {
s4 i;
if (!u) {
- *exceptionptr = new_nullpointerexception();
+ exceptions_throw_nullpointerexception();
return NULL;
}
u2 ch;
if (!u) {
- *exceptionptr = new_nullpointerexception();
+ exceptions_throw_nullpointerexception();
return NULL;
}
java_chararray *a;
if (!text) {
- *exceptionptr = new_nullpointerexception();
+ exceptions_throw_nullpointerexception();
return NULL;
}
*******************************************************************************/
-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;
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;
}
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 */
/* 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;
}
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);