summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vm/Intern.cpp65
-rw-r--r--vm/Intern.h2
-rw-r--r--vm/UtfString.cpp16
-rw-r--r--vm/UtfString.h5
-rw-r--r--vm/alloc/Alloc.cpp5
-rw-r--r--vm/alloc/Alloc.h2
-rw-r--r--vm/oo/Object.h4
-rw-r--r--vm/reflect/Annotation.cpp2
8 files changed, 53 insertions, 48 deletions
diff --git a/vm/Intern.cpp b/vm/Intern.cpp
index 8215107ba..9faca45e0 100644
--- a/vm/Intern.cpp
+++ b/vm/Intern.cpp
@@ -51,22 +51,36 @@ void dvmStringInternShutdown()
gDvm.literalStrings = NULL;
}
+static StringObject* lookupString(HashTable* table, u4 key, StringObject* value)
+{
+ void* entry = dvmHashTableLookup(table, key, (void*)value,
+ dvmHashcmpStrings, false);
+ return (StringObject*)entry;
+}
+
+static StringObject* insertString(HashTable* table, u4 key, StringObject* value)
+{
+ if (dvmIsNonMovingObject(value) == false) {
+ value = (StringObject*)dvmCloneObject(value, ALLOC_NON_MOVING);
+ }
+ void* entry = dvmHashTableLookup(table, key, (void*)value,
+ dvmHashcmpStrings, true);
+ assert(entry == value);
+ return (StringObject*)entry;
+}
+
static StringObject* lookupInternedString(StringObject* strObj, bool isLiteral)
{
StringObject* found;
- u4 hash;
assert(strObj != NULL);
- hash = dvmComputeStringHash(strObj);
+ u4 key = dvmComputeStringHash(strObj);
dvmLockMutex(&gDvm.internLock);
if (isLiteral) {
/*
* Check the literal table for a match.
*/
- StringObject* literal = (StringObject*)dvmHashTableLookup(gDvm.literalStrings,
- hash, strObj,
- dvmHashcmpStrings,
- false);
+ StringObject* literal = lookupString(gDvm.literalStrings, key, strObj);
if (literal != NULL) {
/*
* A match was found in the literal table, the easy case.
@@ -77,50 +91,33 @@ static StringObject* lookupInternedString(StringObject* strObj, bool isLiteral)
* There is no match in the literal table, check the
* interned string table.
*/
- StringObject* interned = (StringObject*)dvmHashTableLookup(gDvm.internedStrings,
- hash, strObj,
- dvmHashcmpStrings,
- false);
+ StringObject* interned = lookupString(gDvm.internedStrings, key, strObj);
if (interned != NULL) {
/*
* A match was found in the interned table. Move the
* matching string to the literal table.
*/
- dvmHashTableRemove(gDvm.internedStrings, hash, interned);
- found = (StringObject*)dvmHashTableLookup(gDvm.literalStrings,
- hash, interned,
- dvmHashcmpStrings,
- true);
- assert(found == interned);
+ dvmHashTableRemove(gDvm.internedStrings, key, interned);
+ found = insertString(gDvm.literalStrings, key, interned);
} else {
/*
* No match in the literal table or the interned
* table. Insert into the literal table.
*/
- found = (StringObject*)dvmHashTableLookup(gDvm.literalStrings,
- hash, strObj,
- dvmHashcmpStrings,
- true);
- assert(found == strObj);
+ found = insertString(gDvm.literalStrings, key, strObj);
}
}
} else {
/*
* Check the literal table for a match.
*/
- found = (StringObject*)dvmHashTableLookup(gDvm.literalStrings,
- hash, strObj,
- dvmHashcmpStrings,
- false);
+ found = lookupString(gDvm.literalStrings, key, strObj);
if (found == NULL) {
/*
* No match was found in the literal table. Insert into
* the intern table.
*/
- found = (StringObject*)dvmHashTableLookup(gDvm.internedStrings,
- hash, strObj,
- dvmHashcmpStrings,
- true);
+ found = insertString(gDvm.internedStrings, key, strObj);
}
}
assert(found != NULL);
@@ -152,19 +149,15 @@ StringObject* dvmLookupImmortalInternedString(StringObject* strObj)
* Returns true if the object is a weak interned string. Any string
* interned by the user is weak.
*/
-bool dvmIsWeakInternedString(const StringObject* strObj)
+bool dvmIsWeakInternedString(StringObject* strObj)
{
- StringObject* found;
- u4 hash;
-
assert(strObj != NULL);
if (gDvm.internedStrings == NULL) {
return false;
}
dvmLockMutex(&gDvm.internLock);
- hash = dvmComputeStringHash(strObj);
- found = (StringObject*)dvmHashTableLookup(gDvm.internedStrings, hash,
- (StringObject*)strObj, dvmHashcmpStrings, false);
+ u4 key = dvmComputeStringHash(strObj);
+ StringObject* found = lookupString(gDvm.internedStrings, key, strObj);
dvmUnlockMutex(&gDvm.internLock);
return found == strObj;
}
diff --git a/vm/Intern.h b/vm/Intern.h
index 6630b69f3..207a038df 100644
--- a/vm/Intern.h
+++ b/vm/Intern.h
@@ -23,7 +23,7 @@ bool dvmStringInternStartup(void);
void dvmStringInternShutdown(void);
StringObject* dvmLookupInternedString(StringObject* strObj);
StringObject* dvmLookupImmortalInternedString(StringObject* strObj);
-bool dvmIsWeakInternedString(const StringObject* strObj);
+bool dvmIsWeakInternedString(StringObject* strObj);
void dvmGcDetachDeadInternedStrings(int (*isUnmarkedObject)(void *));
#endif /*_DALVIK_INTERN*/
diff --git a/vm/UtfString.cpp b/vm/UtfString.cpp
index 17ce40ad5..0b7e4a091 100644
--- a/vm/UtfString.cpp
+++ b/vm/UtfString.cpp
@@ -204,12 +204,18 @@ static inline u4 computeUtf16Hash(const u2* utf16Str, size_t len)
return hash;
}
-u4 dvmComputeStringHash(const StringObject* strObj) {
- const ArrayObject* chars = (ArrayObject*) dvmGetFieldObject((Object*) strObj,
+u4 dvmComputeStringHash(StringObject* strObj) {
+ int hashCode = dvmGetFieldInt(strObj, STRING_FIELDOFF_HASHCODE);
+ if (hashCode != 0) {
+ return hashCode;
+ }
+ int len = dvmGetFieldInt(strObj, STRING_FIELDOFF_COUNT);
+ int offset = dvmGetFieldInt(strObj, STRING_FIELDOFF_OFFSET);
+ ArrayObject* chars = (ArrayObject*) dvmGetFieldObject(strObj,
STRING_FIELDOFF_VALUE);
- int len = dvmGetFieldInt((Object*) strObj, STRING_FIELDOFF_COUNT);
- int offset = dvmGetFieldInt((Object*) strObj, STRING_FIELDOFF_OFFSET);
- return computeUtf16Hash((u2*)(void*)chars->contents + offset, len);
+ hashCode = computeUtf16Hash((u2*)(void*)chars->contents + offset, len);
+ dvmSetFieldInt(strObj, STRING_FIELDOFF_HASHCODE, hashCode);
+ return hashCode;
}
/*
diff --git a/vm/UtfString.h b/vm/UtfString.h
index b577d3a59..488ba9b8a 100644
--- a/vm/UtfString.h
+++ b/vm/UtfString.h
@@ -51,9 +51,10 @@
u4 dvmComputeUtf8Hash(const char* str);
/*
- * Hash function for string objects.
+ * Hash function for string objects. Ensures the hash code field is
+ * populated and returns its value.
*/
-u4 dvmComputeStringHash(const StringObject* strObj);
+u4 dvmComputeStringHash(StringObject* strObj);
/*
* Create a java.lang.String[] from an array of C strings.
diff --git a/vm/alloc/Alloc.cpp b/vm/alloc/Alloc.cpp
index a77c770bc..0fe22eaec 100644
--- a/vm/alloc/Alloc.cpp
+++ b/vm/alloc/Alloc.cpp
@@ -366,3 +366,8 @@ bool dvmIsHeapAddress(void *address)
{
return dvmHeapSourceContainsAddress(address);
}
+
+bool dvmIsNonMovingObject(const Object* object)
+{
+ return true;
+}
diff --git a/vm/alloc/Alloc.h b/vm/alloc/Alloc.h
index c215fc2b3..41a346651 100644
--- a/vm/alloc/Alloc.h
+++ b/vm/alloc/Alloc.h
@@ -144,4 +144,6 @@ void dvmClearGrowthLimit(void);
*/
bool dvmIsHeapAddress(void *address);
+bool dvmIsNonMovingObject(const Object* object);
+
#endif /*_DALVIK_ALLOC_ALLOC*/
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index c647a905a..0b4d740e4 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -242,9 +242,7 @@ struct DataObject : Object {
* Currently this is just equal to DataObject, and we pull the fields out
* like we do for any other object.
*/
-struct StringObject {
- Object obj; /* MUST be first item */
-
+struct StringObject : Object {
/* variable #of u4 slots; u8 uses 2 slots */
u4 instanceData[1];
};
diff --git a/vm/reflect/Annotation.cpp b/vm/reflect/Annotation.cpp
index 6b33af369..f01591031 100644
--- a/vm/reflect/Annotation.cpp
+++ b/vm/reflect/Annotation.cpp
@@ -1490,7 +1490,7 @@ bool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName,
}
*pName = (StringObject*) avalue.value.l;
- assert(*pName == NULL || (*pName)->obj.clazz == gDvm.classJavaLangString);
+ assert(*pName == NULL || (*pName)->clazz == gDvm.classJavaLangString);
ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "accessFlags");
if (ptr == NULL) {