implement String.intern()

This commit is contained in:
Joel Dice 2007-07-28 18:02:32 -06:00
parent 0e373727a2
commit c96a4a5b39
6 changed files with 109 additions and 7 deletions

View File

@ -33,10 +33,6 @@ public final class String implements Comparable<String> {
}
}
public static String valueOf(int v) {
return valueOf((long) v);
}
public int length() {
return length;
}
@ -217,7 +213,13 @@ public final class String implements Comparable<String> {
return ((char[]) data)[index + offset];
} else {
return (char) ((byte[]) data)[index + offset];
}
}
}
public native String intern();
public static String valueOf(int v) {
return valueOf((long) v);
}
public static String valueOf(long v) {

View File

@ -16,7 +16,7 @@ src = src
classpath = classpath
test = test
input = $(cls)/Threads.class
input = $(cls)/Exceptions.class
cxx = g++
cc = gcc

View File

@ -445,6 +445,12 @@ Array_makeObjectArray(Thread* t, jclass, jclass elementType, jint length)
return pushReference(t, makeObjectArray(t, *elementType, length, true));
}
jobject
String_intern(Thread* t, jobject this_)
{
return pushReference(t, intern(t, *this_));
}
void
System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
jint dstOffset, jint length)
@ -649,6 +655,9 @@ populateBuiltinMap(Thread* t, object map)
{ "Java_java_lang_Runtiime_exit",
reinterpret_cast<void*>(::Runtime_exit) },
{ "Java_java_lang_String_intern",
reinterpret_cast<void*>(::String_intern) },
{ "Java_java_lang_Thread_doStart",
reinterpret_cast<void*>(::Thread_doStart) },
{ "Java_java_lang_Thread_interrupt",

View File

@ -573,6 +573,7 @@ parsePool(Thread* t, Stream& s)
object bytes = arrayBody(t, pool, intArrayBody(t, o, 1) - 1);
object value = makeString
(t, bytes, 0, byteArrayLength(t, bytes) - 1, 0);
value = intern(t, value);
set(t, arrayBody(t, pool, i), value);
} break;
@ -1253,6 +1254,12 @@ removeMonitor(Thread* t, object o)
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
}
void
removeString(Thread* t, object o)
{
hashMapRemove(t, t->vm->stringMap, o, stringHash, objectEqual);
}
} // namespace
namespace vm {
@ -1274,6 +1281,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
bootstrapClassMap(0),
builtinMap(0),
monitorMap(0),
stringMap(0),
types(0),
finalizers(0),
tenuredFinalizers(0),
@ -1373,6 +1381,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
m->classMap = makeHashMap(this, NormalMap, 0, 0);
m->builtinMap = makeHashMap(this, NormalMap, 0, 0);
m->monitorMap = makeHashMap(this, WeakMap, 0, 0);
m->stringMap = makeHashMap(this, WeakMap, 0, 0);
populateBuiltinMap(t, m->builtinMap);
@ -2234,6 +2243,23 @@ objectMonitor(Thread* t, object o)
}
}
object
intern(Thread* t, object s)
{
ACQUIRE(t, t->vm->referenceLock);
object n = hashMapFindNode(t, t->vm->stringMap, s, stringHash, stringEqual);
if (n) {
return jreferenceTarget(t, tripleFirst(t, n));
} else {
PROTECT(t, s);
hashMapInsert(t, t->vm->stringMap, s, 0, stringHash);
addFinalizer(t, s, removeString);
return s;
}
}
void
collect(Thread* t, Heap::CollectionType type)
{
@ -2248,6 +2274,7 @@ collect(Thread* t, Heap::CollectionType type)
v->visit(&(m->bootstrapClassMap));
v->visit(&(m->builtinMap));
v->visit(&(m->monitorMap));
v->visit(&(m->stringMap));
v->visit(&(m->types));
for (Thread* t = m->rootThread; t; t = t->peer) {

View File

@ -1114,6 +1114,7 @@ class Machine {
object bootstrapClassMap;
object builtinMap;
object monitorMap;
object stringMap;
object types;
object finalizers;
object tenuredFinalizers;
@ -1777,6 +1778,14 @@ hash(const int8_t* s, unsigned length)
return h;
}
inline uint32_t
hash(const uint16_t* s, unsigned length)
{
uint32_t h = 0;
for (unsigned i = 0; i < length; ++i) h = (h * 31) + s[i];
return h;
}
inline unsigned
baseSize(Thread* t, object o, object class_)
{
@ -1847,6 +1856,12 @@ byteArrayHash(Thread* t, object array)
return hash(&byteArrayBody(t, array, 0), byteArrayLength(t, array));
}
inline uint32_t
charArrayHash(Thread* t, object array)
{
return hash(&charArrayBody(t, array, 0), charArrayLength(t, array));
}
inline bool
byteArrayEqual(Thread* t, object a, object b)
{
@ -1856,6 +1871,52 @@ byteArrayEqual(Thread* t, object a, object b)
byteArrayLength(t, a)) == 0);
}
inline uint32_t
stringHash(Thread* t, object s)
{
if (stringHashCode(t, s) == 0) {
object data = stringData(t, s);
if (objectClass(t, data)
== arrayBody(t, t->vm->types, Machine::ByteArrayType))
{
stringHashCode(t, s) = byteArrayHash(t, data);
} else {
stringHashCode(t, s) = charArrayHash(t, data);
}
}
return stringHashCode(t, s);
}
inline uint16_t
stringCharAt(Thread* t, object s, int i)
{
object data = stringData(t, s);
if (objectClass(t, data)
== arrayBody(t, t->vm->types, Machine::ByteArrayType))
{
return byteArrayBody(t, data, i);
} else {
return charArrayBody(t, data, i);
}
}
inline bool
stringEqual(Thread* t, object a, object b)
{
if (a == b) {
return true;
} else if (stringLength(t, a) == stringLength(t, b)) {
for (int i = 0; i < stringLength(t, a); ++i) {
if (stringCharAt(t, a, i) != stringCharAt(t, b, i)) {
return false;
}
}
return true;
} else {
return false;
}
}
inline bool
intArrayEqual(Thread* t, object a, object b)
{
@ -2122,6 +2183,9 @@ interrupt(Thread*, Thread* target)
target->systemThread->interrupt();
}
object
intern(Thread* t, object s);
void
exit(Thread* t);

View File

@ -121,7 +121,7 @@
(object data)
(int32_t offset)
(int32_t length)
(int32_t hash))
(int32_t hashCode))
(type thread java/lang/Thread
(extends jobject)