mirror of
https://github.com/corda/corda.git
synced 2025-06-17 14:48:16 +00:00
implement String.intern()
This commit is contained in:
@ -33,10 +33,6 @@ public final class String implements Comparable<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String valueOf(int v) {
|
|
||||||
return valueOf((long) v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int length() {
|
public int length() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -220,6 +216,12 @@ public final class String implements Comparable<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public native String intern();
|
||||||
|
|
||||||
|
public static String valueOf(int v) {
|
||||||
|
return valueOf((long) v);
|
||||||
|
}
|
||||||
|
|
||||||
public static String valueOf(long v) {
|
public static String valueOf(long v) {
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
return valueOf('0');
|
return valueOf('0');
|
||||||
|
2
makefile
2
makefile
@ -16,7 +16,7 @@ src = src
|
|||||||
classpath = classpath
|
classpath = classpath
|
||||||
test = test
|
test = test
|
||||||
|
|
||||||
input = $(cls)/Threads.class
|
input = $(cls)/Exceptions.class
|
||||||
|
|
||||||
cxx = g++
|
cxx = g++
|
||||||
cc = gcc
|
cc = gcc
|
||||||
|
@ -445,6 +445,12 @@ Array_makeObjectArray(Thread* t, jclass, jclass elementType, jint length)
|
|||||||
return pushReference(t, makeObjectArray(t, *elementType, length, true));
|
return pushReference(t, makeObjectArray(t, *elementType, length, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject
|
||||||
|
String_intern(Thread* t, jobject this_)
|
||||||
|
{
|
||||||
|
return pushReference(t, intern(t, *this_));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
|
System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
|
||||||
jint dstOffset, jint length)
|
jint dstOffset, jint length)
|
||||||
@ -649,6 +655,9 @@ populateBuiltinMap(Thread* t, object map)
|
|||||||
{ "Java_java_lang_Runtiime_exit",
|
{ "Java_java_lang_Runtiime_exit",
|
||||||
reinterpret_cast<void*>(::Runtime_exit) },
|
reinterpret_cast<void*>(::Runtime_exit) },
|
||||||
|
|
||||||
|
{ "Java_java_lang_String_intern",
|
||||||
|
reinterpret_cast<void*>(::String_intern) },
|
||||||
|
|
||||||
{ "Java_java_lang_Thread_doStart",
|
{ "Java_java_lang_Thread_doStart",
|
||||||
reinterpret_cast<void*>(::Thread_doStart) },
|
reinterpret_cast<void*>(::Thread_doStart) },
|
||||||
{ "Java_java_lang_Thread_interrupt",
|
{ "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 bytes = arrayBody(t, pool, intArrayBody(t, o, 1) - 1);
|
||||||
object value = makeString
|
object value = makeString
|
||||||
(t, bytes, 0, byteArrayLength(t, bytes) - 1, 0);
|
(t, bytes, 0, byteArrayLength(t, bytes) - 1, 0);
|
||||||
|
value = intern(t, value);
|
||||||
set(t, arrayBody(t, pool, i), value);
|
set(t, arrayBody(t, pool, i), value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1253,6 +1254,12 @@ removeMonitor(Thread* t, object o)
|
|||||||
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
|
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeString(Thread* t, object o)
|
||||||
|
{
|
||||||
|
hashMapRemove(t, t->vm->stringMap, o, stringHash, objectEqual);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
@ -1274,6 +1281,7 @@ Machine::Machine(System* system, Heap* heap, ClassFinder* classFinder):
|
|||||||
bootstrapClassMap(0),
|
bootstrapClassMap(0),
|
||||||
builtinMap(0),
|
builtinMap(0),
|
||||||
monitorMap(0),
|
monitorMap(0),
|
||||||
|
stringMap(0),
|
||||||
types(0),
|
types(0),
|
||||||
finalizers(0),
|
finalizers(0),
|
||||||
tenuredFinalizers(0),
|
tenuredFinalizers(0),
|
||||||
@ -1373,6 +1381,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
m->classMap = makeHashMap(this, NormalMap, 0, 0);
|
m->classMap = makeHashMap(this, NormalMap, 0, 0);
|
||||||
m->builtinMap = makeHashMap(this, NormalMap, 0, 0);
|
m->builtinMap = makeHashMap(this, NormalMap, 0, 0);
|
||||||
m->monitorMap = makeHashMap(this, WeakMap, 0, 0);
|
m->monitorMap = makeHashMap(this, WeakMap, 0, 0);
|
||||||
|
m->stringMap = makeHashMap(this, WeakMap, 0, 0);
|
||||||
|
|
||||||
populateBuiltinMap(t, m->builtinMap);
|
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
|
void
|
||||||
collect(Thread* t, Heap::CollectionType type)
|
collect(Thread* t, Heap::CollectionType type)
|
||||||
{
|
{
|
||||||
@ -2248,6 +2274,7 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
v->visit(&(m->bootstrapClassMap));
|
v->visit(&(m->bootstrapClassMap));
|
||||||
v->visit(&(m->builtinMap));
|
v->visit(&(m->builtinMap));
|
||||||
v->visit(&(m->monitorMap));
|
v->visit(&(m->monitorMap));
|
||||||
|
v->visit(&(m->stringMap));
|
||||||
v->visit(&(m->types));
|
v->visit(&(m->types));
|
||||||
|
|
||||||
for (Thread* t = m->rootThread; t; t = t->peer) {
|
for (Thread* t = m->rootThread; t; t = t->peer) {
|
||||||
|
@ -1114,6 +1114,7 @@ class Machine {
|
|||||||
object bootstrapClassMap;
|
object bootstrapClassMap;
|
||||||
object builtinMap;
|
object builtinMap;
|
||||||
object monitorMap;
|
object monitorMap;
|
||||||
|
object stringMap;
|
||||||
object types;
|
object types;
|
||||||
object finalizers;
|
object finalizers;
|
||||||
object tenuredFinalizers;
|
object tenuredFinalizers;
|
||||||
@ -1777,6 +1778,14 @@ hash(const int8_t* s, unsigned length)
|
|||||||
return h;
|
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
|
inline unsigned
|
||||||
baseSize(Thread* t, object o, object class_)
|
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));
|
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
|
inline bool
|
||||||
byteArrayEqual(Thread* t, object a, object b)
|
byteArrayEqual(Thread* t, object a, object b)
|
||||||
{
|
{
|
||||||
@ -1856,6 +1871,52 @@ byteArrayEqual(Thread* t, object a, object b)
|
|||||||
byteArrayLength(t, a)) == 0);
|
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
|
inline bool
|
||||||
intArrayEqual(Thread* t, object a, object b)
|
intArrayEqual(Thread* t, object a, object b)
|
||||||
{
|
{
|
||||||
@ -2122,6 +2183,9 @@ interrupt(Thread*, Thread* target)
|
|||||||
target->systemThread->interrupt();
|
target->systemThread->interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
intern(Thread* t, object s);
|
||||||
|
|
||||||
void
|
void
|
||||||
exit(Thread* t);
|
exit(Thread* t);
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@
|
|||||||
(object data)
|
(object data)
|
||||||
(int32_t offset)
|
(int32_t offset)
|
||||||
(int32_t length)
|
(int32_t length)
|
||||||
(int32_t hash))
|
(int32_t hashCode))
|
||||||
|
|
||||||
(type thread java/lang/Thread
|
(type thread java/lang/Thread
|
||||||
(extends jobject)
|
(extends jobject)
|
||||||
|
Reference in New Issue
Block a user