Add a reference table implementation.

This is suitable for pinned array references and the like.

I've also brought in some of the human-readable type printing stuff
for the benefit of the reference table dumping code.

This patch includes tests, but doesn't yet wire anything up.

Change-Id: Iaf6066201bbd254e033dee4fd0b8dfd0bc17afa9
diff --git a/src/utils.cc b/src/utils.cc
new file mode 100644
index 0000000..419eb1c
--- /dev/null
+++ b/src/utils.cc
@@ -0,0 +1,71 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: enh@google.com (Elliott Hughes)
+
+#include "object.h"
+#include "utils.h"
+
+namespace art {
+
+std::string PrettyDescriptor(const StringPiece& descriptor) {
+  // Count the number of '['s to get the dimensionality.
+  const char* c = descriptor.data();
+  size_t dim = 0;
+  while (*c == '[') {
+    dim++;
+    c++;
+  }
+
+  // Reference or primitive?
+  if (*c == 'L') {
+    // "[[La/b/C;" -> "a.b.C[][]".
+    c++; // Skip the 'L'.
+  } else {
+    // "[[B" -> "byte[][]".
+    // To make life easier, we make primitives look like unqualified
+    // reference types.
+    switch (*c) {
+    case 'B': c = "byte;"; break;
+    case 'C': c = "char;"; break;
+    case 'D': c = "double;"; break;
+    case 'F': c = "float;"; break;
+    case 'I': c = "int;"; break;
+    case 'J': c = "long;"; break;
+    case 'S': c = "short;"; break;
+    case 'Z': c = "boolean;"; break;
+    default: return descriptor.ToString();
+    }
+  }
+
+  // At this point, 'c' is a string of the form "fully/qualified/Type;"
+  // or "primitive;". Rewrite the type with '.' instead of '/':
+  std::string result;
+  const char* p = c;
+  while (*p != ';') {
+    char ch = *p++;
+    if (ch == '/') {
+      ch = '.';
+    }
+    result.push_back(ch);
+  }
+  // ...and replace the semicolon with 'dim' "[]" pairs:
+  while (dim--) {
+    result += "[]";
+  }
+  return result;
+}
+
+std::string PrettyType(const Object* obj) {
+  if (obj == NULL) {
+    return "null";
+  }
+  if (obj->GetClass() == NULL) {
+    return "(raw)";
+  }
+  std::string result(PrettyDescriptor(obj->GetClass()->GetDescriptor()));
+  if (obj->IsClass()) {
+    result += "<" + PrettyDescriptor(obj->AsClass()->GetDescriptor()) + ">";
+  }
+  return result;
+}
+
+}  // namespace art