diff options
-rw-r--r-- | vm/Intern.cpp | 65 | ||||
-rw-r--r-- | vm/Intern.h | 2 | ||||
-rw-r--r-- | vm/UtfString.cpp | 16 | ||||
-rw-r--r-- | vm/UtfString.h | 5 | ||||
-rw-r--r-- | vm/alloc/Alloc.cpp | 5 | ||||
-rw-r--r-- | vm/alloc/Alloc.h | 2 | ||||
-rw-r--r-- | vm/oo/Object.h | 4 | ||||
-rw-r--r-- | vm/reflect/Annotation.cpp | 2 |
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) { |