Convert Class::descriptor_ from StringPiece to String (as part of image loading)

Change-Id: Iab5ffa353661a7c06ee79af1f40d399a53777174
diff --git a/src/object.h b/src/object.h
index 2b5a054..8efa059 100644
--- a/src/object.h
+++ b/src/object.h
@@ -367,8 +367,8 @@
     return name_;
   }
 
-  const String* GetDescriptor() const {
-    return descriptor_;
+  const String* GetSignature() const {
+    return signature_;
   }
 
   Class* GetDeclaringClass() const {
@@ -573,7 +573,7 @@
   // the method descriptor would be
   //
   //   (IDLjava/lang/Thread;)Ljava/lang/Object;
-  String* descriptor_;
+  String* signature_;
 
   // Method prototype descriptor string (return and argument types).
   uint32_t proto_idx_;
@@ -599,16 +599,16 @@
 
 class Array : public Object {
  public:
-  static size_t Size(size_t component_count,
-                     size_t component_size) {
+  static size_t SizeOf(size_t component_count,
+                       size_t component_size) {
     return sizeof(Array) + component_count * component_size;
   }
 
   static Array* Alloc(Class* array_class,
                       size_t component_count,
                       size_t component_size) {
-    size_t size = Size(component_count, component_size);
-    Array* array = Heap::AllocObject(array_class, size)->AsArray();
+    size_t size = SizeOf(component_count, component_size);
+    Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
     if (array != NULL) {
       array->SetLength(component_count);
     }
@@ -816,30 +816,15 @@
     return component_type_;
   }
 
-  static size_t GetTypeSize(const StringPiece& descriptor) {
-    switch (descriptor[0]) {
-    case 'B': return 1;  // byte
-    case 'C': return 2;  // char
-    case 'D': return 8;  // double
-    case 'F': return 4;  // float
-    case 'I': return 4;  // int
-    case 'J': return 8;  // long
-    case 'S': return 2;  // short
-    case 'Z': return 1;  // boolean
-    case 'L': return sizeof(Object*);
-    case '[': return sizeof(Array*);
-    default:
-      LOG(ERROR) << "Unknown type " << descriptor;
-      return 0;
-    }
-  }
+  static size_t GetTypeSize(String* descriptor);
 
   size_t GetComponentSize() const {
     return GetTypeSize(component_type_->descriptor_);
   }
 
-  const StringPiece& GetDescriptor() const {
-    DCHECK_NE(0, descriptor_.size());
+  const String* GetDescriptor() const {
+    DCHECK(descriptor_ != NULL);
+    // DCHECK_NE(0, descriptor_->GetLength());  // TODO: keep?
     return descriptor_;
   }
 
@@ -880,13 +865,11 @@
   // Returns true if this class is in the same packages as that class.
   bool IsInSamePackage(const Class* that) const;
 
-  static bool IsInSamePackage(const StringPiece& descriptor1,
-                              const StringPiece& descriptor2);
+  static bool IsInSamePackage(const String* descriptor1,
+                              const String* descriptor2);
 
   // Returns true if this class represents an array class.
-  bool IsArray() const {
-    return GetDescriptor()[0] == '[';  // TODO: avoid parsing the descriptor
-  }
+  bool IsArray() const;
 
   // Returns true if the class is an interface.
   bool IsInterface() const {
@@ -1052,20 +1035,11 @@
   bool IsSubClass(const Class* klass) const;
 
  public:  // TODO: private
-  // leave space for instance data; we could access fields directly if
-  // we freeze the definition of java/lang/Class
-#define CLASS_FIELD_SLOTS 1
-  // Class.#0 name
-  uint32_t instance_data_[CLASS_FIELD_SLOTS];
-#undef CLASS_FIELD_SLOTS
+  // descriptor for the class such as "java.lang.Class" or "[C"
+  String* name_;  // TODO initialize
 
-  // UTF-8 descriptor for the class from constant pool
-  // ("Ljava/lang/Class;"), or on heap if generated ("[C")
-  StringPiece descriptor_;
-
-  // Proxy classes have their descriptor allocated on the native heap.
-  // When this field is non-NULL it must be explicitly freed.
-  std::string* descriptor_alloc_;
+  // descriptor for the class such as "Ljava/lang/Class;" or "[C"
+  String* descriptor_;
 
   // access flags; low 16 bits are defined by VM spec
   uint32_t access_flags_;  // TODO: make an instance field?
@@ -1218,7 +1192,7 @@
 }
 
 inline size_t Array::SizeOf() const {
-  return Size(GetLength(), klass_->GetComponentSize());
+  return SizeOf(GetLength(), klass_->GetComponentSize());
 }
 
 class DataObject : public Object {
@@ -1329,14 +1303,18 @@
     return string;
   }
 
-  static void InitClasses(Class* java_lang_String);
+  static void InitClass(Class* java_lang_String);
 
   static String* Alloc(Class* java_lang_String,
                        int32_t utf16_length) {
+    return Alloc(java_lang_String, CharArray::Alloc(utf16_length));
+  }
+
+  static String* Alloc(Class* java_lang_String,
+                       CharArray* array) {
     String* string = down_cast<String*>(java_lang_String->NewInstance());
-    CharArray* array = CharArray::Alloc(utf16_length);
     string->array_ = array;
-    string->count_ = utf16_length;
+    string->count_ = array->GetLength();
     return string;
   }
 
@@ -1464,6 +1442,29 @@
     return true;
   }
 
+  // Create a modified UTF-8 encoded std::string from a java/lang/String object.
+  std::string ToModifiedUtf8() const {
+    std::string result;
+    for (uint32_t i = 0; i < GetLength(); i++) {
+      uint16_t ch = CharAt(i);
+      // The most common case is (ch > 0 && ch <= 0x7f).
+      if (ch == 0 || ch > 0x7f) {
+        if (ch > 0x07ff) {
+          result.push_back((ch >> 12) | 0xe0);
+          result.push_back(((ch >> 6) & 0x3f) | 0x80);
+          result.push_back((ch & 0x3f) | 0x80);
+        } else { // (ch > 0x7f || ch == 0)
+          result.push_back((ch >> 6) | 0xc0);
+          result.push_back((ch & 0x3f) | 0x80);
+        }
+      } else {
+        result.push_back(ch);
+      }
+    }
+    return result;
+  }
+
+
  private:
   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
   CharArray* array_;
@@ -1484,6 +1485,28 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(String);
 };
 
+inline size_t Class::GetTypeSize(String* descriptor) {
+  switch (descriptor->CharAt(0)) {
+  case 'B': return 1;  // byte
+  case 'C': return 2;  // char
+  case 'D': return 8;  // double
+  case 'F': return 4;  // float
+  case 'I': return 4;  // int
+  case 'J': return 8;  // long
+  case 'S': return 2;  // short
+  case 'Z': return 1;  // boolean
+  case 'L': return sizeof(Object*);
+  case '[': return sizeof(Array*);
+  default:
+    LOG(ERROR) << "Unknown type " << descriptor;
+    return 0;
+  }
+}
+
+inline bool Class::IsArray() const {
+  return GetDescriptor()->CharAt(0) == '[';  // TODO: avoid parsing the descriptor
+}
+
 class InterfaceEntry {
  public:
   InterfaceEntry() : klass_(NULL), method_index_array_(NULL) {