mirror of
https://github.com/corda/corda.git
synced 2025-01-28 23:24:29 +00:00
implement String.intern()
This commit is contained in:
parent
0e373727a2
commit
c96a4a5b39
@ -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) {
|
||||
|
2
makefile
2
makefile
@ -16,7 +16,7 @@ src = src
|
||||
classpath = classpath
|
||||
test = test
|
||||
|
||||
input = $(cls)/Threads.class
|
||||
input = $(cls)/Exceptions.class
|
||||
|
||||
cxx = g++
|
||||
cc = gcc
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user