/* src/vm/string.c - java.lang.String related functions
- Copyright (C) 1996-2005, 2006, 2007 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
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: string.c 8295 2007-08-11 17:57:24Z michi $
-
*/
#include <assert.h>
+#include "vmcore/system.h"
+
#include "vm/types.h"
#include "vm/global.h"
#include "threads/lock-common.h"
+#include "vm/array.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/primitive.h"
#endif
+/* XXX preliminary typedef, will be removed once string.c and utf8.c are
+ unified. */
+
+#if defined(ENABLE_HANDLES)
+typedef heap_java_lang_String heapstring_t;
+#else
+typedef java_lang_String heapstring_t;
+#endif
+
+
/* string_init *****************************************************************
Initialize the string hashtable lock.
bool string_init(void)
{
+ TRACESUBSYSTEMINITIALIZATION("string_init");
+
/* create string (javastring) hashtable */
hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE);
void stringtable_update(void)
{
- java_lang_String *js;
- java_chararray *a;
- literalstring *s; /* hashtable entry */
+ heapstring_t *js;
+ java_chararray_t *a;
+ literalstring *s; /* hashtable entry */
int i;
for (i = 0; i < hashtable_string.size; i++) {
s = hashtable_string.ptr[i];
if (s) {
while (s) {
- js = (java_lang_String *) s->string;
+ js = (heapstring_t *) s->string;
if ((js == NULL) || (js->value == NULL)) {
/* error in hashtable found */
vm_abort("stringtable_update: invalid literalstring in hashtable");
}
- LLNI_field_get_ref(js, value, a);
+ a = js->value;
if (!js->header.vftbl)
/* vftbl of javastring is NULL */
u4 utflength; /* length of utf-string if uncompressed */
java_handle_t *o;
java_lang_String *s; /* result-string */
- java_chararray *a;
+ java_handle_chararray_t *a;
u4 i;
assert(buffer);
utf_ptr = buffer;
for (i = 0; i < utflength; i++)
- a->data[i] = utf_nextu2((char **) &utf_ptr);
+ LLNI_array_direct(a, i) = utf_nextu2((char **) &utf_ptr);
/* set fields of the javastring-object */
java_handle_t *javastring_safe_new_from_utf8(const char *text)
{
- java_handle_t *o;
- java_chararray *a;
- java_lang_String *s;
+ java_handle_t *o;
+ java_handle_chararray_t *a;
+ java_lang_String *s;
s4 nbytes;
s4 len;
/* decompress UTF-8 string */
- utf8_safe_convert_to_u2s(text, nbytes, a->data);
+ utf8_safe_convert_to_u2s(text, nbytes, LLNI_array_data(a));
/* set fields of the String object */
{
char *utf_ptr; /* current utf character in utf string */
u4 utflength; /* length of utf-string if uncompressed */
- java_handle_t *o;
- java_chararray *a;
- java_lang_String *s;
+ java_handle_t *o;
+ java_handle_chararray_t *a;
+ java_lang_String *s;
s4 i;
if (u == NULL) {
/* decompress utf-string */
for (i = 0; i < utflength; i++)
- a->data[i] = utf_nextu2(&utf_ptr);
+ LLNI_array_direct(a, i) = utf_nextu2(&utf_ptr);
/* set fields of the javastring-object */
{
char *utf_ptr; /* current utf character in utf string */
u4 utflength; /* length of utf-string if uncompressed */
- java_handle_t *o;
- java_chararray *a;
- java_lang_String *s;
+ java_handle_t *o;
+ java_handle_chararray_t *a;
+ java_lang_String *s;
s4 i;
u2 ch;
ch = utf_nextu2(&utf_ptr);
if (ch == '/')
ch = '.';
- a->data[i] = ch;
+ LLNI_array_direct(a, i) = ch;
}
/* set fields of the javastring-object */
{
s4 i;
s4 len; /* length of the string */
- java_handle_t *o;
- java_lang_String *s;
- java_chararray *a;
+ java_handle_t *o;
+ java_lang_String *s;
+ java_handle_chararray_t *a;
if (text == NULL) {
exceptions_throw_nullpointerexception();
/* copy text */
for (i = 0; i < len; i++)
- a->data[i] = text[i];
+ LLNI_array_direct(a, i) = text[i];
/* set fields of the javastring-object */
char *javastring_tochar(java_handle_t *so)
{
- java_lang_String *s = (java_lang_String *) so;
- java_chararray *a;
+ java_lang_String *s = (java_lang_String *) so;
+ java_handle_chararray_t *a;
+ int32_t count;
+ int32_t offset;
char *buf;
s4 i;
if (!a)
return "";
- buf = MNEW(char, LLNI_field_direct(s, count) + 1);
+ LLNI_field_get_val(s, count, count);
+ LLNI_field_get_val(s, offset, offset);
- for (i = 0; i < LLNI_field_direct(s, count); i++)
- buf[i] = a->data[LLNI_field_direct(s, offset) + i];
+ buf = MNEW(char, count + 1);
+
+ for (i = 0; i < count; i++)
+ buf[i] = LLNI_array_direct(a, offset + i);
buf[i] = '\0';
utf *javastring_toutf(java_handle_t *string, bool isclassname)
{
- java_lang_String *s;
+ java_lang_String *s;
+ java_handle_chararray_t *value;
+ int32_t count;
+ int32_t offset;
s = (java_lang_String *) string;
if (s == NULL)
return utf_null;
- return utf_new_u2(LLNI_field_direct(s, value)->data + LLNI_field_direct(s, offset), LLNI_field_direct(s, count), isclassname);
+ LLNI_field_get_ref(s, value, value);
+
+ if (value == NULL)
+ return utf_null;
+
+ LLNI_field_get_val(s, count, count);
+ LLNI_field_get_val(s, offset, offset);
+
+ return utf_new_u2(LLNI_array_data(value) + offset, count, isclassname);
}
/* literalstring_u2 ************************************************************
- Searches for the javastring with the specified u2-array in the
+ Searches for the literalstring with the specified u2-array in the
string hashtable, if there is no such string a new one is created.
If copymode is true a copy of the u2-array is made.
*******************************************************************************/
-java_object_t *literalstring_u2(java_chararray *a, u4 length, u4 offset,
- bool copymode)
+static java_object_t *literalstring_u2(java_chararray_t *a, u4 length,
+ u4 offset, bool copymode)
{
literalstring *s; /* hashtable element */
- java_lang_String *js; /* u2-array wrapped in javastring */
- java_chararray *ca; /* copy of u2-array */
+ heapstring_t *js; /* u2-array wrapped in javastring */
+ java_chararray_t *ca; /* copy of u2-array */
u4 key;
u4 slot;
u2 i;
s = hashtable_string.ptr[slot];
while (s) {
- js = (java_lang_String *) s->string;
+ js = (heapstring_t *) s->string;
if (length == js->count) {
/* compare text */
/* string already in hashtable, free memory */
if (!copymode)
- mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10);
+ mem_free(a, sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10);
LOCK_MONITOR_EXIT(lock_hashtable_string);
if (copymode) {
/* create copy of u2-array for new javastring */
- u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10;
+ u4 arraysize = sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10;
ca = mem_alloc(arraysize);
/* memcpy(ca, a, arraysize); */
- memcpy(&(ca->header), &(a->header), sizeof(java_arrayheader));
+ memcpy(&(ca->header), &(a->header), sizeof(java_array_t));
memcpy(&(ca->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
} else {
/* create new javastring */
- js = NEW(java_lang_String);
+ js = NEW(heapstring_t);
#if defined(ENABLE_STATISTICS)
if (opt_stat)
- size_string += sizeof(java_lang_String);
+ size_string += sizeof(heapstring_t);
#endif
#if defined(ENABLE_THREADS)
/* 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 */
+ u4 i;
+ literalstring *s;
+ literalstring *nexts;
+ heapstring_t *tmpjs;
+ hashtable newhash; /* the new hashtable */
/* create new hashtable, double the size */
while (s) {
nexts = s->hashlink;
- tmpjs = (java_lang_String *) s->string;
+ tmpjs = (heapstring_t *) s->string;
slot = unicode_hashkey(tmpjs->value->data, tmpjs->count) & (newhash.size - 1);
s->hashlink = newhash.ptr[slot];
/* literalstring_new ***********************************************************
- Creates a new javastring with the text of the utf-symbol and inserts it into
- the string hashtable.
+ Creates a new literalstring with the text of the utf-symbol and inserts
+ it into the string hashtable.
*******************************************************************************/
java_object_t *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 */
- java_chararray *a; /* u2-array constructed from utf string */
- u4 i;
+ u4 utflength; /* length of utf-string if uncompressed */
+ java_chararray_t *a; /* u2-array constructed from utf string */
+ u4 i;
utf_ptr = u->text;
utflength = utf_get_number_of_u2s(u);
/* allocate memory */
- a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
+ a = mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10);
/* convert utf-string to u2-array */
for (i = 0; i < utflength; i++)
/* literalstring_free **********************************************************
- Removes a javastring from memory.
+ Removes a literalstring from memory.
*******************************************************************************/
-void literalstring_free(java_object_t* string)
+#if 0
+/* TWISTI This one is currently not used. */
+
+static void literalstring_free(java_object_t* string)
{
- java_lang_String *s;
- java_chararray *a;
+ heapstring_t *s;
+ java_chararray_t *a;
- s = (java_lang_String *) string;
+ s = (heapstring_t *) string;
a = s->value;
/* dispose memory of java.lang.String object */
- FREE(s, java_lang_String);
+ FREE(s, heapstring_t);
/* dispose memory of java-characterarray */
- FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
+ FREE(a, sizeof(java_chararray_t) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
+}
+#endif
+
+
+/* javastring_intern ***********************************************************
+
+ Intern the given Java string.
+
+ XXX NOTE: Literal Strings are direct references since they are not placed
+ onto the GC-Heap. That's why this function looks so "different".
+
+*******************************************************************************/
+
+java_handle_t *javastring_intern(java_handle_t *s)
+{
+ java_lang_String *so;
+ java_chararray_t *value;
+ int32_t count;
+ int32_t offset;
+/* java_lang_String *o; */
+ java_object_t *o; /* XXX see note above */
+
+ so = (java_lang_String *) s;
+
+ value = LLNI_field_direct(so, value); /* XXX see note above */
+ LLNI_field_get_val(so, count, count);
+ LLNI_field_get_val(so, offset, offset);
+
+ o = literalstring_u2(value, count, offset, true);
+
+ return LLNI_WRAP(o); /* XXX see note above */
+}
+
+
+/* javastring_fprint ***********************************************************
+
+ Print the given Java string to the given stream.
+
+*******************************************************************************/
+
+void javastring_fprint(java_handle_t *s, FILE *stream)
+{
+ java_lang_String *so;
+ java_handle_chararray_t *value;
+ int32_t count;
+ int32_t offset;
+ uint16_t c;
+ int i;
+
+ so = (java_lang_String *) s;
+
+ LLNI_field_get_ref(so, value, value);
+ LLNI_field_get_val(so, count, count);
+ LLNI_field_get_val(so, offset, offset);
+
+ for (i = offset; i < offset + count; i++) {
+ c = LLNI_array_direct(value, i);
+ fputc(c, stream);
+ }
}