diff options
-rw-r--r-- | vm/Misc.cpp | 17 | ||||
-rw-r--r-- | vm/Misc.h | 8 | ||||
-rw-r--r-- | vm/ReferenceTable.cpp | 80 | ||||
-rw-r--r-- | vm/UtfString.cpp | 102 | ||||
-rw-r--r-- | vm/UtfString.h | 14 | ||||
-rw-r--r-- | vm/interp/Stack.cpp | 9 | ||||
-rw-r--r-- | vm/native/InternalNative.cpp | 7 |
7 files changed, 127 insertions, 110 deletions
diff --git a/vm/Misc.cpp b/vm/Misc.cpp index 3b1179e44..3cbd5633c 100644 --- a/vm/Misc.cpp +++ b/vm/Misc.cpp @@ -266,6 +266,23 @@ std::string dvmHumanReadableDescriptor(const char* descriptor) { return result; } +std::string dvmHumanReadableType(const Object* obj) +{ + if (obj == NULL) { + return "(null)"; + } + if (obj->clazz == NULL) { + /* should only be possible right after a plain dvmMalloc() */ + return "(raw)"; + } + std::string result(dvmHumanReadableDescriptor(obj->clazz->descriptor)); + if (dvmIsClassObject(obj)) { + const ClassObject* clazz = reinterpret_cast<const ClassObject*>(obj); + result += "<" + dvmHumanReadableDescriptor(clazz->descriptor) + ">"; + } + return result; +} + /* * Return a newly-allocated string for the "dot version" of the class * name for the given type descriptor. That is, The initial "L" and @@ -147,6 +147,14 @@ char* dvmDotToSlash(const char* str); */ std::string dvmHumanReadableDescriptor(const char* descriptor); +/** + * Returns a human-readable string form of the name of the class of + * the given object. So given a java.lang.String, the output would + * be "java.lang.String". Given an array of int, the output would be "int[]". + * Given String.class, the output would be "java.lang.Class<java.lang.String>". + */ +std::string dvmHumanReadableType(const Object* obj); + /* * Return a newly-allocated string for the "dot version" of the class * name for the given type descriptor. That is, The initial "L" and diff --git a/vm/ReferenceTable.cpp b/vm/ReferenceTable.cpp index 764093fa6..1438bdcf4 100644 --- a/vm/ReferenceTable.cpp +++ b/vm/ReferenceTable.cpp @@ -209,24 +209,23 @@ static void logObject(const Object* obj, size_t elems, int identical, int equiv) return; } - /* handle "raw" dvmMalloc case */ - const char* descriptor = - (obj->clazz != NULL) ? obj->clazz->descriptor : "(raw)"; - - char elemStr[16]; - - if (elems != 0) { - snprintf(elemStr, sizeof(elemStr), " [%zd]", elems); + std::string className; + if (obj->clazz == NULL) { + /* handle "raw" dvmMalloc case */ + className = "(raw)"; } else { - elemStr[0] = '\0'; + className = dvmHumanReadableType(obj); + if (elems != 0) { + className += dvmStringPrintf(" (%zd elements)", elems); + } } + size_t total = identical + equiv + 1; + std::string msg(dvmStringPrintf("%5d of %s", total, className.c_str())); if (identical + equiv != 0) { - LOGW("%5d of %s%s (%d unique)", identical + equiv +1, - descriptor, elemStr, equiv +1); - } else { - LOGW("%5d of %s%s", identical + equiv +1, descriptor, elemStr); + msg += dvmStringPrintf(" (%d unique instances)", equiv + 1); } + LOGW("%s", msg.c_str()); } /* @@ -248,32 +247,47 @@ void dvmDumpReferenceTableContents(Object* const* refs, size_t count, */ const size_t kLast = 10; LOGW("Last %d entries in %s reference table:", kLast, descr); - int start = count - kLast; - if (start < 0) - start = 0; + int first = count - kLast; + if (first < 0) { + first = 0; + } - size_t idx, elems; - for (idx = start; idx < count; idx++) { + for (int idx = count - 1; idx >= first; --idx) { const Object* ref = refs[idx]; - if (ref == NULL) + if (ref == NULL) { continue; - - elems = getElementCount(ref); - + } if (ref->clazz == NULL) { /* should only be possible right after a plain dvmMalloc() */ size_t size = dvmObjectSizeInHeap(ref); - LOGW("%5d: %p cls=(raw) (%zd bytes)", idx, ref, size); - } else if (dvmIsClassObject(ref)) { - ClassObject* clazz = (ClassObject*) ref; - LOGW("%5d: %p cls=%s '%s'", idx, ref, ref->clazz->descriptor, - clazz->descriptor); - } else if (elems != 0) { - LOGW("%5d: %p cls=%s [%zd]", - idx, ref, ref->clazz->descriptor, elems); - } else { - LOGW("%5d: %p cls=%s", idx, ref, ref->clazz->descriptor); + LOGW("%5d: %p (raw) (%zd bytes)", idx, ref, size); + continue; + } + + std::string className(dvmHumanReadableType(ref)); + + std::string extras; + size_t elems = getElementCount(ref); + if (elems != 0) { + extras += dvmStringPrintf(" (%zd elements)", elems); + } else if (ref->clazz == gDvm.classJavaLangString) { + const StringObject* str = + reinterpret_cast<const StringObject*>(ref); + extras += " \""; + size_t count = 0; + char* s = dvmCreateCstrFromString(str); + char* p = s; + for (; *p && count < 16; ++p, ++count) { + extras += *p; + } + if (*p == 0) { + extras += "\""; + } else { + extras += dvmStringPrintf("... (%d chars)", dvmStringLen(str)); + } + free(s); } + LOGW("%5d: %p %s%s", idx, ref, className.c_str(), extras.c_str()); } /* @@ -307,6 +321,8 @@ void dvmDumpReferenceTableContents(Object* const* refs, size_t count, LOGW("%s reference table summary (%d entries):", descr, count); size_t equiv, identical; equiv = identical = 0; + size_t idx; + size_t elems; for (idx = 1; idx < count; idx++) { elems = getElementCount(refs[idx-1]); diff --git a/vm/UtfString.cpp b/vm/UtfString.cpp index 566650746..05bac533b 100644 --- a/vm/UtfString.cpp +++ b/vm/UtfString.cpp @@ -211,8 +211,8 @@ u4 dvmComputeStringHash(StringObject* strObj) { } int len = dvmGetFieldInt(strObj, STRING_FIELDOFF_COUNT); int offset = dvmGetFieldInt(strObj, STRING_FIELDOFF_OFFSET); - ArrayObject* chars = (ArrayObject*) dvmGetFieldObject(strObj, - STRING_FIELDOFF_VALUE); + ArrayObject* chars = + (ArrayObject*) dvmGetFieldObject(strObj, STRING_FIELDOFF_VALUE); hashCode = computeUtf16Hash((u2*)(void*)chars->contents + offset, len); dvmSetFieldInt(strObj, STRING_FIELDOFF_HASHCODE, hashCode); return hashCode; @@ -281,29 +281,25 @@ StringObject* dvmCreateStringFromUnicode(const u2* unichars, int len) * * Returns NULL if the object is NULL. */ -char* dvmCreateCstrFromString(StringObject* jstr) +char* dvmCreateCstrFromString(const StringObject* jstr) { - char* newStr; - ArrayObject* chars; - int len, byteLen, offset; - const u2* data; - assert(gDvm.classJavaLangString != NULL); - - if (jstr == NULL) + if (jstr == NULL) { return NULL; + } - len = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT); - offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET); - chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr, - STRING_FIELDOFF_VALUE); - data = (const u2*)(void*)chars->contents + offset; + int len = dvmGetFieldInt(jstr, STRING_FIELDOFF_COUNT); + int offset = dvmGetFieldInt(jstr, STRING_FIELDOFF_OFFSET); + ArrayObject* chars = + (ArrayObject*) dvmGetFieldObject(jstr, STRING_FIELDOFF_VALUE); + const u2* data = (const u2*)(void*)chars->contents + offset; assert(offset + len <= (int) chars->length); - byteLen = utf16_utf8ByteLen(data, len); - newStr = (char*) malloc(byteLen+1); - if (newStr == NULL) + int byteLen = utf16_utf8ByteLen(data, len); + char* newStr = (char*) malloc(byteLen+1); + if (newStr == NULL) { return NULL; + } convertUtf16ToUtf8(newStr, data, len); return newStr; @@ -313,12 +309,10 @@ char* dvmCreateCstrFromString(StringObject* jstr) * Create a UTF-8 C string from a region of a java/lang/String. (Used by * the JNI GetStringUTFRegion call.) */ -void dvmCreateCstrFromStringRegion(StringObject* jstr, int start, int len, - char* buf) +void dvmCreateCstrFromStringRegion(const StringObject* jstr, + int start, int len, char* buf) { - const u2* data; - - data = dvmStringChars(jstr) + start; + const u2* data = dvmStringChars(jstr) + start; convertUtf16ToUtf8(buf, data, len); } @@ -327,22 +321,18 @@ void dvmCreateCstrFromStringRegion(StringObject* jstr, int start, int len, * * Does not include the terminating null byte. */ -int dvmStringUtf8ByteLen(StringObject* jstr) +int dvmStringUtf8ByteLen(const StringObject* jstr) { - ArrayObject* chars; - int len, offset; - const u2* data; - assert(gDvm.classJavaLangString != NULL); - - if (jstr == NULL) + if (jstr == NULL) { return 0; // should we throw something? assert? + } - len = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT); - offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET); - chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr, - STRING_FIELDOFF_VALUE); - data = (const u2*)(void*)chars->contents + offset; + int len = dvmGetFieldInt(jstr, STRING_FIELDOFF_COUNT); + int offset = dvmGetFieldInt(jstr, STRING_FIELDOFF_OFFSET); + ArrayObject* chars = + (ArrayObject*) dvmGetFieldObject(jstr, STRING_FIELDOFF_VALUE); + const u2* data = (const u2*)(void*)chars->contents + offset; assert(offset + len <= (int) chars->length); return utf16_utf8ByteLen(data, len); @@ -351,31 +341,27 @@ int dvmStringUtf8ByteLen(StringObject* jstr) /* * Get the string's length. */ -int dvmStringLen(StringObject* jstr) +int dvmStringLen(const StringObject* jstr) { - return dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT); + return dvmGetFieldInt(jstr, STRING_FIELDOFF_COUNT); } /* * Get the char[] object from the String. */ -ArrayObject* dvmStringCharArray(StringObject* jstr) +ArrayObject* dvmStringCharArray(const StringObject* jstr) { - return (ArrayObject*) dvmGetFieldObject((Object*) jstr, - STRING_FIELDOFF_VALUE); + return (ArrayObject*) dvmGetFieldObject(jstr, STRING_FIELDOFF_VALUE); } /* * Get the string's data. */ -const u2* dvmStringChars(StringObject* jstr) +const u2* dvmStringChars(const StringObject* jstr) { - ArrayObject* chars; - int offset; - - offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET); - chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr, - STRING_FIELDOFF_VALUE); + int offset = dvmGetFieldInt(jstr, STRING_FIELDOFF_OFFSET); + ArrayObject* chars = + (ArrayObject*) dvmGetFieldObject(jstr, STRING_FIELDOFF_VALUE); return (const u2*)(void*)chars->contents + offset; } @@ -391,24 +377,22 @@ int dvmHashcmpStrings(const void* vstrObj1, const void* vstrObj2) { const StringObject* strObj1 = (const StringObject*) vstrObj1; const StringObject* strObj2 = (const StringObject*) vstrObj2; - ArrayObject* chars1; - ArrayObject* chars2; - int len1, len2, offset1, offset2; assert(gDvm.classJavaLangString != NULL); /* get offset and length into char array; all values are in 16-bit units */ - len1 = dvmGetFieldInt((Object*) strObj1, STRING_FIELDOFF_COUNT); - offset1 = dvmGetFieldInt((Object*) strObj1, STRING_FIELDOFF_OFFSET); - len2 = dvmGetFieldInt((Object*) strObj2, STRING_FIELDOFF_COUNT); - offset2 = dvmGetFieldInt((Object*) strObj2, STRING_FIELDOFF_OFFSET); - if (len1 != len2) + int len1 = dvmGetFieldInt(strObj1, STRING_FIELDOFF_COUNT); + int offset1 = dvmGetFieldInt(strObj1, STRING_FIELDOFF_OFFSET); + int len2 = dvmGetFieldInt(strObj2, STRING_FIELDOFF_COUNT); + int offset2 = dvmGetFieldInt(strObj2, STRING_FIELDOFF_OFFSET); + if (len1 != len2) { return len1 - len2; + } - chars1 = (ArrayObject*) dvmGetFieldObject((Object*) strObj1, - STRING_FIELDOFF_VALUE); - chars2 = (ArrayObject*) dvmGetFieldObject((Object*) strObj2, - STRING_FIELDOFF_VALUE); + ArrayObject* chars1 = + (ArrayObject*) dvmGetFieldObject(strObj1, STRING_FIELDOFF_VALUE); + ArrayObject* chars2 = + (ArrayObject*) dvmGetFieldObject(strObj2, STRING_FIELDOFF_VALUE); /* damage here actually indicates a broken java/lang/String */ assert(offset1 + len1 <= (int) chars1->length); diff --git a/vm/UtfString.h b/vm/UtfString.h index 13832dfc2..b236ce552 100644 --- a/vm/UtfString.h +++ b/vm/UtfString.h @@ -123,35 +123,35 @@ StringObject* dvmCreateStringFromUnicode(const u2* unichars, int len); * * Returns NULL if "jstr" is NULL. */ -char* dvmCreateCstrFromString(StringObject* jstr); +char* dvmCreateCstrFromString(const StringObject* jstr); /* * Create a UTF-8 C string from a region of a java/lang/String. (Used by * the JNI GetStringUTFRegion call.) */ -void dvmCreateCstrFromStringRegion(StringObject* jstr, int start, int len, - char* buf); +void dvmCreateCstrFromStringRegion(const StringObject* jstr, + int start, int len, char* buf); /* * Compute the length in bytes of the modified UTF-8 representation of a * string. */ -int dvmStringUtf8ByteLen(StringObject* jstr); +int dvmStringUtf8ByteLen(const StringObject* jstr); /* * Get the length in Unicode characters of a string. */ -int dvmStringLen(StringObject* jstr); +int dvmStringLen(const StringObject* jstr); /* * Get the char[] object from the String. */ -ArrayObject* dvmStringCharArray(StringObject* jstr); +ArrayObject* dvmStringCharArray(const StringObject* jstr); /* * Get a pointer to the Unicode data. */ -const u2* dvmStringChars(StringObject* jstr); +const u2* dvmStringChars(const StringObject* jstr); /* * Compare two string objects. (This is a dvmHashTableLookup() callback.) diff --git a/vm/interp/Stack.cpp b/vm/interp/Stack.cpp index 3c0d9da08..98c209baf 100644 --- a/vm/interp/Stack.cpp +++ b/vm/interp/Stack.cpp @@ -637,7 +637,7 @@ static void throwArgumentTypeMismatch(int argIndex, ClassObject* expected, DataO std::string expectedClassName(dvmHumanReadableDescriptor(expected->descriptor)); std::string actualClassName; if (arg != NULL) { - actualClassName = dvmHumanReadableDescriptor(arg->clazz->descriptor); + actualClassName = dvmHumanReadableType(arg); } else { actualClassName = "null"; } @@ -1163,11 +1163,8 @@ static void printWaitMessage(const DebugOutputTarget* target, const char* detail if (obj->clazz != gDvm.classJavaLangClass) { // I(16573) - waiting on <0xf5feda38> (a java.util.LinkedList) - msg += "(a " + dvmHumanReadableDescriptor(obj->clazz->descriptor) + ")"; - } else { - // I(16573) - waiting on <0xf5ed54f8> (java.lang.Class<java.lang.ref.ReferenceQueue>) - ClassObject* clazz = reinterpret_cast<ClassObject*>(obj); - msg += "(java.lang.Class<" + dvmHumanReadableDescriptor(clazz->descriptor) + ">)"; + // I(16573) - waiting on <0xf5ed54f8> (a java.lang.Class<java.lang.ref.ReferenceQueue>) + msg += "(a " + dvmHumanReadableType(obj) + ")"; } if (thread != NULL) { diff --git a/vm/native/InternalNative.cpp b/vm/native/InternalNative.cpp index 708deab41..7ba1a6463 100644 --- a/vm/native/InternalNative.cpp +++ b/vm/native/InternalNative.cpp @@ -165,12 +165,7 @@ bool dvmVerifyObjectInClass(Object* obj, ClassObject* clazz) { } std::string expectedClassName(dvmHumanReadableDescriptor(clazz->descriptor)); - std::string actualClassName; - if (obj != NULL) { - actualClassName = dvmHumanReadableDescriptor(obj->clazz->descriptor); - } else { - actualClassName = "null"; - } + std::string actualClassName(dvmHumanReadableType(obj)); dvmThrowExceptionFmt(exceptionClass, "expected receiver of type %s, but got %s", expectedClassName.c_str(), actualClassName.c_str()); return false; |