Various bits of cleanup.

Most notable: PrettyField now includes the type (but, like PrettyMethod,
lets you turn this off), and there's a new PrettyClass, and PrettyType
has been renamed to PrettyTypeOf.

I've also moved the dalvik "sync" stuff into files named "monitor", and
made some of the implementation details private.

Change-Id: I39ea79b45e173f9ebbf9878bcead207766a5653f
diff --git a/build/Android.common.mk b/build/Android.common.mk
index deb1df0..33e59cc 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -115,6 +115,7 @@
 	src/managed_register_arm.cc \
 	src/managed_register_x86.cc \
 	src/memory_region.cc \
+	src/monitor.cc \
 	src/mspace.c \
 	src/mutex.cc \
 	src/object.cc \
@@ -130,7 +131,6 @@
 	src/stub_arm.cc \
 	src/stub_x86.cc \
 	src/sun_misc_Unsafe.cc \
-	src/sync.cc \
 	src/thread.cc \
 	src/thread_list.cc \
 	src/utf.cc \
diff --git a/src/check_jni.cc b/src/check_jni.cc
index 61be30e..73c35b5 100644
--- a/src/check_jni.cc
+++ b/src/check_jni.cc
@@ -375,7 +375,7 @@
           return;
         } else {
           if (!obj->InstanceOf(field_type)) {
-            LOG(ERROR) << "JNI ERROR: attempt to set field " << PrettyField(f) << " with value of wrong type: " << PrettyType(obj);
+            LOG(ERROR) << "JNI ERROR: attempt to set field " << PrettyField(f) << " with value of wrong type: " << PrettyTypeOf(obj);
             JniAbort();
             return;
           }
@@ -419,7 +419,7 @@
     DCHECK(f_type != NULL);
     Class* c = o->GetClass();
     if (c->FindInstanceField(f->GetName()->ToModifiedUtf8(), f_type) == NULL) {
-      LOG(ERROR) << "JNI ERROR: jfieldID " << PrettyField(f) << " not valid for an object of class " << PrettyType(o);
+      LOG(ERROR) << "JNI ERROR: jfieldID " << PrettyField(f) << " not valid for an object of class " << PrettyTypeOf(o);
       JniAbort();
     }
   }
@@ -464,7 +464,7 @@
     Class* c = Decode<Class*>(ts, java_class);
     const Field* f = DecodeField(fid);
     if (f->GetDeclaringClass() != c) {
-      LOG(ERROR) << "JNI ERROR: static jfieldID " << fid << " not valid for class " << PrettyDescriptor(c->GetDescriptor());
+      LOG(ERROR) << "JNI ERROR: static jfieldID " << fid << " not valid for class " << PrettyClass(c);
       JniAbort();
     }
   }
@@ -483,7 +483,7 @@
     Class* c = Decode<Class*>(ts, java_class);
     const Method* m = DecodeMethod(mid);
     if (!c->IsAssignableFrom(m->GetDeclaringClass())) {
-      LOG(ERROR) << "JNI ERROR: can't call static " << PrettyMethod(m) << " on class " << PrettyDescriptor(c->GetDescriptor());
+      LOG(ERROR) << "JNI ERROR: can't call static " << PrettyMethod(m) << " on class " << PrettyClass(c);
       JniAbort();
     }
   }
@@ -500,7 +500,7 @@
     Object* o = Decode<Object*>(ts, java_object);
     const Method* m = DecodeMethod(mid);
     if (!o->InstanceOf(m->GetDeclaringClass())) {
-      LOG(ERROR) << "JNI ERROR: can't call " << PrettyMethod(m) << " on instance of " << PrettyType(o);
+      LOG(ERROR) << "JNI ERROR: can't call " << PrettyMethod(m) << " on instance of " << PrettyTypeOf(o);
       JniAbort();
     }
   }
@@ -608,7 +608,7 @@
           } else if (c == kInvalidIndirectRefObject || !Heap::IsHeapAddress(c)) {
             StringAppendF(&msg, "%p(INVALID)", jc);
           } else {
-            msg += PrettyDescriptor(c->GetDescriptor());
+            msg += PrettyClass(c);
             if (!entry) {
               StringAppendF(&msg, " (%p)", jc);
             }
@@ -755,7 +755,7 @@
       LOG(ERROR) << "JNI ERROR: jarray is an invalid " << GetIndirectRefKind(java_array) << ": " << reinterpret_cast<void*>(java_array);
       JniAbort();
     } else if (!a->IsArrayInstance()) {
-      LOG(ERROR) << "JNI ERROR: jarray argument has non-array type: " << PrettyType(a);
+      LOG(ERROR) << "JNI ERROR: jarray argument has non-array type: " << PrettyTypeOf(a);
       JniAbort();
     }
   }
@@ -952,7 +952,7 @@
       break;
     }
     if (!okay) {
-      LOG(ERROR) << "JNI ERROR: " << what << " has wrong type: " << PrettyType(obj);
+      LOG(ERROR) << "JNI ERROR: " << what << " has wrong type: " << PrettyTypeOf(obj);
       JniAbort();
     }
   }
diff --git a/src/class_linker.cc b/src/class_linker.cc
index b9c6ed8..e3b4eea 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -7,7 +7,6 @@
 #include <utility>
 #include <vector>
 
-#include "UniquePtr.h"
 #include "casts.h"
 #include "class_loader.h"
 #include "dex_cache.h"
@@ -16,11 +15,12 @@
 #include "heap.h"
 #include "intern_table.h"
 #include "logging.h"
+#include "monitor.h"
 #include "object.h"
 #include "runtime.h"
 #include "space.h"
-#include "sync.h"
 #include "thread.h"
+#include "UniquePtr.h"
 #include "utils.h"
 
 namespace art {
@@ -1222,7 +1222,7 @@
       klass->GetStatus() == Class::kStatusVerified ||
       klass->GetStatus() == Class::kStatusInitializing ||
       klass->GetStatus() == Class::kStatusError)
-          << PrettyDescriptor(klass->GetDescriptor()) << " is " << klass->GetStatus();
+          << PrettyClass(klass) << " is " << klass->GetStatus();
 
   Thread* self = Thread::Current();
 
diff --git a/src/compiler/Dalvik.h b/src/compiler/Dalvik.h
index b2c62bf..d57b72e 100644
--- a/src/compiler/Dalvik.h
+++ b/src/compiler/Dalvik.h
@@ -20,17 +20,18 @@
 #ifndef DALVIK_COMMON_H_
 #define DALVIK_COMMON_H_
 
+#include <assert.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <assert.h>
-#include "logging.h"
-#include "object.h"
-#include "thread.h"
+
 #include "class_linker.h"
 #include "compiler.h"
 #include "dex_cache.h"
-#include "sync.h"
+#include "logging.h"
+#include "monitor.h"
+#include "object.h"
+#include "thread.h"
 #include "utils.h"
 
 // From Common.h
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index fbdfb2e..59aadcf 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -926,7 +926,7 @@
     loadValueDirectFixed(cUnit, rlSrc, r1);  // Get obj
     oatLockCallTemps(cUnit);  // Prepare for explicit register usage
     genNullCheck(cUnit, rlSrc.sRegLow, r1, mir);
-    loadWordDisp(cUnit, rSELF, Thread::IdOffset().Int32Value(), r3);
+    loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r3);
     newLIR3(cUnit, kThumb2Ldrex, r2, r1,
             Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
     // Align owner
@@ -976,7 +976,7 @@
     oatLockCallTemps(cUnit);  // Prepare for explicit register usage
     genNullCheck(cUnit, rlSrc.sRegLow, r1, mir);
     loadWordDisp(cUnit, r1, Object::MonitorOffset().Int32Value(), r2); // Get lock
-    loadWordDisp(cUnit, rSELF, Thread::IdOffset().Int32Value(), r3);
+    loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r3);
     // Is lock unheld on lock or held by us (==threadId) on unlock?
     opRegRegImm(cUnit, kOpAnd, r12, r2, (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
     // Align owner
diff --git a/src/java_lang_System.cc b/src/java_lang_System.cc
index 398eeb9..fc13839 100644
--- a/src/java_lang_System.cc
+++ b/src/java_lang_System.cc
@@ -105,7 +105,7 @@
 namespace {
 
 void ThrowArrayStoreException_NotAnArray(const char* identifier, Object* array) {
-  std::string actualType(PrettyType(array));
+  std::string actualType(PrettyTypeOf(array));
   Thread::Current()->ThrowNewException("Ljava/lang/ArrayStoreException;", "%s is not an array: %s", identifier, actualType.c_str());
 }
 
@@ -153,8 +153,8 @@
   if (srcComponentType->IsPrimitive() || dstComponentType->IsPrimitive()) {
     // If one of the arrays holds a primitive type the other array must hold the exact same type.
     if (srcComponentType->IsPrimitive() != dstComponentType->IsPrimitive() || srcComponentType != dstComponentType) {
-      std::string srcType(PrettyType(srcArray));
-      std::string dstType(PrettyType(dstArray));
+      std::string srcType(PrettyTypeOf(srcArray));
+      std::string dstType(PrettyTypeOf(dstArray));
       self->ThrowNewException("Ljava/lang/ArrayStoreException;",
           "Incompatible types: src=%s, dst=%s", srcType.c_str(), dstType.c_str());
       return;
@@ -175,7 +175,7 @@
       move32(dstBytes + dstPos * 8, srcBytes + srcPos * 8, length * 8);
       break;
     default:
-      LOG(FATAL) << "Unknown primitive array type: " << PrettyType(srcArray);
+      LOG(FATAL) << "Unknown primitive array type: " << PrettyTypeOf(srcArray);
     }
 
     return;
@@ -229,8 +229,8 @@
   move32(dstBytes + dstPos * width, srcBytes + srcPos * width, copyCount * width);
   Heap::WriteBarrier(dstArray);
   if (copyCount != length) {
-    std::string actualSrcType(PrettyType(srcObj[copyCount]));
-    std::string dstType(PrettyType(dstArray));
+    std::string actualSrcType(PrettyTypeOf(srcObj[copyCount]));
+    std::string dstType(PrettyTypeOf(dstArray));
     self->ThrowNewException("Ljava/lang/ArrayStoreException;",
         "source[%d] of type %s cannot be stored in destination array of type %s",
         srcPos + copyCount, actualSrcType.c_str(), dstType.c_str());
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 5b4bf21..94ef729 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -82,9 +82,8 @@
   if (env->check_jni) {
     size_t entry_count = locals.Capacity();
     if (entry_count > 16) {
-      std::string class_descriptor(PrettyDescriptor(obj->GetClass()->GetDescriptor()));
       LOG(WARNING) << "Warning: more than 16 JNI local references: "
-                   << entry_count << " (most recent was a " << class_descriptor << ")";
+                   << entry_count << " (most recent was a " << PrettyTypeOf(obj) << ")";
       locals.Dump();
       // TODO: dvmDumpThread(dvmThreadSelf(), false);
       // dvmAbort();
@@ -384,7 +383,7 @@
 }
 
 void ThrowAIOOBE(ScopedJniThreadState& ts, Array* array, jsize start, jsize length, const char* identifier) {
-  std::string type(PrettyType(array));
+  std::string type(PrettyTypeOf(array));
   ts.Self()->ThrowNewException("Ljava/lang/ArrayIndexOutOfBoundsException;",
       "%s offset=%d length=%d %s.length=%d",
       type.c_str(), start, length, identifier, array->GetLength());
@@ -722,7 +721,7 @@
       return JNI_ERR;
     }
 
-    LOG(INFO) << "Throwing " << PrettyType(Decode<Throwable*>(ts, exception.get()))
+    LOG(INFO) << "Throwing " << PrettyTypeOf(Decode<Throwable*>(ts, exception.get()))
               << ": " << msg;
     ts.Self()->SetException(Decode<Throwable*>(ts, exception.get()));
 
@@ -751,11 +750,11 @@
     jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
     if (mid == NULL) {
       LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
-                   << PrettyType(original_exception);
+                   << PrettyTypeOf(original_exception);
     } else {
       env->CallVoidMethod(exception.get(), mid);
       if (self->IsExceptionPending()) {
-        LOG(WARNING) << "JNI WARNING: " << PrettyType(self->GetException())
+        LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(self->GetException())
                      << " thrown while calling printStackTrace";
         self->ClearException();
       }
@@ -2164,8 +2163,7 @@
     Class* c = Decode<Class*>(ts, java_class);
 
     if (ts.Vm()->verbose_jni) {
-      LOG(INFO) << "[Unregistering JNI native methods for "
-                << PrettyDescriptor(c->GetDescriptor()) << "]";
+      LOG(INFO) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
     }
 
     for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
diff --git a/src/sync.cc b/src/monitor.cc
similarity index 97%
rename from src/sync.cc
rename to src/monitor.cc
index b07ec35..1a5e6c9 100644
--- a/src/sync.cc
+++ b/src/monitor.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "sync.h"
+#include "monitor.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -61,9 +61,7 @@
  *
  * For an in-depth description of the mechanics of thin-vs-fat locking,
  * read the paper referred to above.
- */
-
-/*
+ *
  * Monitors provide:
  *  - mutually exclusive access to resources
  *  - a way for multiple threads to wait for notification
@@ -76,6 +74,23 @@
  *
  * TODO: the various members of monitor are not SMP-safe.
  */
+
+
+/*
+ * Monitor accessor.  Extracts a monitor structure pointer from a fat
+ * lock.  Performs no error checking.
+ */
+#define LW_MONITOR(x) \
+  ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | LW_SHAPE_MASK)))
+
+/*
+ * Lock recursion count field.  Contains a count of the number of times
+ * a lock has been recursively acquired.
+ */
+#define LW_LOCK_COUNT_MASK 0x1fff
+#define LW_LOCK_COUNT_SHIFT 19
+#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK)
+
 Monitor::Monitor(Object* obj)
     : owner_(NULL),
       lock_count_(0),
diff --git a/src/sync.h b/src/monitor.h
similarity index 83%
rename from src/sync.h
rename to src/monitor.h
index f19237e..8c22fb1 100644
--- a/src/sync.h
+++ b/src/monitor.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ART_SRC_SYNC_H_
-#define ART_SRC_SYNC_H_
+#ifndef ART_SRC_MONITOR_H_
+#define ART_SRC_MONITOR_H_
 
 #include <pthread.h>
 #include <stdint.h>
@@ -44,13 +44,6 @@
 #define LW_HASH_STATE(x) (((x) >> LW_HASH_STATE_SHIFT) & LW_HASH_STATE_MASK)
 
 /*
- * Monitor accessor.  Extracts a monitor structure pointer from a fat
- * lock.  Performs no error checking.
- */
-#define LW_MONITOR(x) \
-  ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | LW_SHAPE_MASK)))
-
-/*
  * Lock owner field.  Contains the thread id of the thread currently
  * holding the lock.
  */
@@ -58,16 +51,8 @@
 #define LW_LOCK_OWNER_SHIFT 3
 #define LW_LOCK_OWNER(x) (((x) >> LW_LOCK_OWNER_SHIFT) & LW_LOCK_OWNER_MASK)
 
-/*
- * Lock recursion count field.  Contains a count of the numer of times
- * a lock has been recursively acquired.
- */
-#define LW_LOCK_COUNT_MASK 0x1fff
-#define LW_LOCK_COUNT_SHIFT 19
-#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK)
-
-struct Object;
-struct Thread;
+class Object;
+class Thread;
 
 class Monitor {
  public:
@@ -135,4 +120,4 @@
 
 }  // namespace art
 
-#endif  // ART_SRC_SYNC_H_
+#endif  // ART_SRC_MONITOR_H_
diff --git a/src/object.cc b/src/object.cc
index 1e0d5c6..c54364f 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -10,14 +10,14 @@
 
 #include "class_linker.h"
 #include "class_loader.h"
+#include "dex_cache.h"
+#include "dex_file.h"
 #include "globals.h"
 #include "heap.h"
 #include "intern_table.h"
 #include "logging.h"
-#include "dex_cache.h"
-#include "dex_file.h"
+#include "monitor.h"
 #include "runtime.h"
-#include "sync.h"
 
 namespace art {
 
@@ -766,8 +766,8 @@
 
 void Class::CanPutArrayElementFromCode(const Class* object_class, const Class* array_class) {
   if (!CanPutArrayElement(object_class, array_class)) {
-    LOG(ERROR) << "Can't put a " << PrettyDescriptor(object_class->GetDescriptor())
-               << " into a " << PrettyDescriptor(array_class->GetDescriptor());
+    LOG(ERROR) << "Can't put a " << PrettyClass(object_class)
+               << " into a " << PrettyClass(array_class);
     UNIMPLEMENTED(FATAL) << "need to throw ArrayStoreException and unwind stack";
   }
 }
diff --git a/src/object.h b/src/object.h
index b57c0e9..59909e1 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1467,18 +1467,16 @@
 
   void SetClassSize(size_t new_class_size) {
     DCHECK(new_class_size >= GetClassSize())
-            << " class=" << PrettyType(this)
+            << " class=" << PrettyTypeOf(this)
             << " new_class_size=" << new_class_size
             << " GetClassSize=" << GetClassSize();
-    SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size,
-               false);
+    SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
   }
 
   size_t GetObjectSize() const {
     CHECK(!IsVariableSize());
     CHECK(sizeof(size_t) == sizeof(int32_t));
-    size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_),
-                               false);
+    size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), false);
     CHECK_GE(result, sizeof(Object));
     return result;
   }
diff --git a/src/reference_table.cc b/src/reference_table.cc
index df3daf2..1b20b52 100644
--- a/src/reference_table.cc
+++ b/src/reference_table.cc
@@ -108,7 +108,7 @@
     return;
   }
 
-  std::string className(PrettyType(obj));
+  std::string className(PrettyTypeOf(obj));
   if (obj->IsClass()) {
     // We're summarizing multiple instances, so using the exemplar
     // Class' type parameter here would be misleading.
@@ -165,7 +165,7 @@
       continue;
     }
 
-    std::string className(PrettyType(ref));
+    std::string className(PrettyTypeOf(ref));
 
     std::string extras;
     size_t elems = GetElementCount(ref);
diff --git a/src/thread.cc b/src/thread.cc
index ed82989..b11dbbd 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1115,8 +1115,7 @@
     uint32_t native_pc = pc_trace->Get(i);
     Class* klass = method->GetDeclaringClass();
     const DexFile& dex_file = class_linker->FindDexFile(klass->GetDexCache());
-    String* readable_descriptor = String::AllocFromModifiedUtf8(
-        PrettyDescriptor(klass->GetDescriptor()).c_str());
+    String* readable_descriptor = String::AllocFromModifiedUtf8(PrettyClass(klass).c_str());
 
     // Allocate element, potentially triggering GC
     StackTraceElement* obj =
diff --git a/src/thread.h b/src/thread.h
index 6c76aeb..c362a43 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -470,7 +470,7 @@
     return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
   }
 
-  static ThreadOffset IdOffset() {
+  static ThreadOffset ThinLockIdOffset() {
     return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
   }
 
diff --git a/src/utils.cc b/src/utils.cc
index d146166..08ab705 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -97,11 +97,16 @@
   return result;
 }
 
-std::string PrettyField(const Field* f) {
+std::string PrettyField(const Field* f, bool with_type) {
   if (f == NULL) {
     return "null";
   }
-  std::string result(PrettyDescriptor(f->GetDeclaringClass()->GetDescriptor()));
+  std::string result;
+  if (with_type) {
+    result += PrettyDescriptor(f->GetType()->GetDescriptor());
+    result += ' ';
+  }
+  result += PrettyDescriptor(f->GetDeclaringClass()->GetDescriptor());
   result += '.';
   result += f->GetName()->ToModifiedUtf8();
   return result;
@@ -123,7 +128,7 @@
   return result;
 }
 
-std::string PrettyType(const Object* obj) {
+std::string PrettyTypeOf(const Object* obj) {
   if (obj == NULL) {
     return "null";
   }
@@ -137,6 +142,17 @@
   return result;
 }
 
+std::string PrettyClass(const Class* c) {
+  if (c == NULL) {
+    return "null";
+  }
+  std::string result;
+  result += "java.lang.Class<";
+  result += PrettyDescriptor(c->GetDescriptor());
+  result += ">";
+  return result;
+}
+
 std::string MangleForJni(const std::string& s) {
   std::string result;
   size_t char_count = CountModifiedUtf8Chars(s.c_str());
diff --git a/src/utils.h b/src/utils.h
index e6ed1d2..fc58617 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -14,6 +14,7 @@
 
 namespace art {
 
+class Class;
 class Field;
 class Method;
 class Object;
@@ -142,13 +143,16 @@
   return result;
 }
 
+// Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf,
+// one of which is probably more useful to you.
 // Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
 // "[[I" would be "int[][]", "[Ljava/lang/String;" would be
 // "java.lang.String[]", and so forth.
 std::string PrettyDescriptor(const String* descriptor);
 
-// Returns a human-readable signature for 'f'. Something like "a.b.C.f".
-std::string PrettyField(const Field* f);
+// Returns a human-readable signature for 'f'. Something like "a.b.C.f" or
+// "int a.b.C.f" (depending on the value of 'with_type').
+std::string PrettyField(const Field* f, bool with_type = true);
 
 // Returns a human-readable signature for 'm'. Something like "a.b.C.m" or
 // "a.b.C.m(II)V" (depending on the value of 'with_signature').
@@ -158,7 +162,11 @@
 // So given an instance of 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 PrettyType(const Object* obj);
+std::string PrettyTypeOf(const Object* obj);
+
+// Returns a human-readable form of the name of the given class.
+// Given String.class, the output would be "java.lang.Class<java.lang.String>".
+std::string PrettyClass(const Class* c);
 
 // Performs JNI name mangling as described in section 11.3 "Linking Native Methods"
 // of the JNI spec.
diff --git a/src/utils_test.cc b/src/utils_test.cc
index 21167d6..0869b89 100644
--- a/src/utils_test.cc
+++ b/src/utils_test.cc
@@ -56,20 +56,44 @@
   EXPECT_DESCRIPTOR("short", "S");
 }
 
-TEST_F(UtilsTest, PrettyType) {
-  EXPECT_EQ("null", PrettyType(NULL));
+TEST_F(UtilsTest, PrettyTypeOf) {
+  EXPECT_EQ("null", PrettyTypeOf(NULL));
 
   String* s = String::AllocFromModifiedUtf8("");
-  EXPECT_EQ("java.lang.String", PrettyType(s));
+  EXPECT_EQ("java.lang.String", PrettyTypeOf(s));
 
   ShortArray* a = ShortArray::Alloc(2);
-  EXPECT_EQ("short[]", PrettyType(a));
+  EXPECT_EQ("short[]", PrettyTypeOf(a));
 
   Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
   ASSERT_TRUE(c != NULL);
   Object* o = ObjectArray<String>::Alloc(c, 0);
-  EXPECT_EQ("java.lang.String[]", PrettyType(o));
-  EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyType(o->GetClass()));
+  EXPECT_EQ("java.lang.String[]", PrettyTypeOf(o));
+  EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyTypeOf(o->GetClass()));
+}
+
+TEST_F(UtilsTest, PrettyClass) {
+  EXPECT_EQ("null", PrettyClass(NULL));
+  Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+  ASSERT_TRUE(c != NULL);
+  Object* o = ObjectArray<String>::Alloc(c, 0);
+  EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyClass(o->GetClass()));
+}
+
+TEST_F(UtilsTest, PrettyField) {
+  EXPECT_EQ("null", PrettyField(NULL));
+
+  Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
+  Class* int_class = class_linker_->FindPrimitiveClass('I');
+  Class* char_array_class = class_linker_->FindSystemClass("[C");
+
+  Field* f;
+  f = java_lang_String->FindDeclaredInstanceField("count", int_class);
+  EXPECT_EQ("int java.lang.String.count", PrettyField(f));
+  EXPECT_EQ("java.lang.String.count", PrettyField(f, false));
+  f = java_lang_String->FindDeclaredInstanceField("value", char_array_class);
+  EXPECT_EQ("char[] java.lang.String.value", PrettyField(f));
+  EXPECT_EQ("java.lang.String.value", PrettyField(f, false));
 }
 
 TEST_F(UtilsTest, MangleForJni) {