Simplify ClassLinker::LoadClass

Starting out by removing the ClassLinker::LoadClass to not take a
DexFile. Then started pulling threads so that ClassLinker::LoadClass
could take a StringPiece instead of const char*. Finally went through
and removed all uses of StringPiece::data() to make sure things are
clean.

Change-Id: I47cfa0e8e0e35a31e0ebbd0f7d6a105be83ebe88
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 19f2f93..332900b 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -83,9 +83,8 @@
   return reinterpret_cast<Method*>(Heap::AllocRaw(sizeof(Method), java_lang_ref_Method_));
 }
 
-Class* ClassLinker::FindClass(const char* descriptor,
-                              Object* class_loader,
-                              DexFile* dex_file) {
+Class* ClassLinker::FindClass(const StringPiece& descriptor,
+                              Object* class_loader) {
   Thread* self = Thread::Current();
   CHECK(!self->IsExceptionPending());
   // Find the class in the loaded classes table.
@@ -93,51 +92,40 @@
   if (klass == NULL) {
     // Class is not yet loaded.
     const RawDexFile::ClassDef* class_def;
-    if (dex_file == NULL) {
-      // No .dex file specified, search the class path.
-      ClassPathEntry pair = FindInClassPath(descriptor);
-      if (pair.first == NULL) {
-        LG << "Class " << descriptor << " really not found";
-        return NULL;
-      }
-      dex_file = pair.first;
-      class_def = pair.second;
-    } else {
-      class_def = dex_file->GetRaw()->FindClassDef(descriptor);
+    // No .dex file specified, search the class path.
+    ClassPathEntry pair = FindInClassPath(descriptor);
+    if (pair.first == NULL) {
+      LG << "Class " << descriptor << " really not found";
+      return NULL;
     }
+    DexFile* dex_file = pair.first;
+    class_def = pair.second;
     // Load the class from the dex file.
-    if (!strcmp(descriptor, "Ljava/lang/Object;")) {
+    if (descriptor == "Ljava/lang/Object;") {
       klass = java_lang_Object_;
       klass->dex_file_ = dex_file;
       klass->object_size_ = sizeof(Object);
-      if (class_def != NULL) {
-        char_array_class_->super_class_idx_ = class_def->class_idx_;
-      }
-    } else if (!strcmp(descriptor, "Ljava/lang/Class;")) {
+      char_array_class_->super_class_idx_ = class_def->class_idx_;
+    } else if (descriptor == "Ljava/lang/Class;") {
       klass = java_lang_Class_;
       klass->dex_file_ = dex_file;
       klass->object_size_ = sizeof(Class);
-    } else if (!strcmp(descriptor, "Ljava/lang/ref/Field;")) {
+    } else if (descriptor == "Ljava/lang/ref/Field;") {
       klass = java_lang_ref_Field_;
       klass->dex_file_ = dex_file;
       klass->object_size_ = sizeof(Field);
-    } else if (!strcmp(descriptor, "Ljava/lang/ref/Method;")) {
+    } else if (descriptor == "Ljava/lang/ref/Method;") {
       klass = java_lang_ref_Method_;
       klass->dex_file_ = dex_file;
       klass->object_size_ = sizeof(Method);
-    } else if (!strcmp(descriptor, "Ljava/lang/String;")) {
+    } else if (descriptor == "Ljava/lang/String;") {
       klass = java_lang_String_;
       klass->dex_file_ = dex_file;
       klass->object_size_ = sizeof(String);
     } else {
       klass = AllocClass(dex_file);
     }
-    bool is_loaded;
-    if (class_def == NULL) {
-      is_loaded = false;
-    } else {
-      is_loaded = LoadClass(*class_def, klass);
-    }
+    bool is_loaded = LoadClass(*class_def, klass);
     if (!is_loaded) {
       // TODO: this occurs only when a dex file is provided.
       LG << "Class not found";  // TODO: NoClassDefFoundError
@@ -192,7 +180,7 @@
   return klass;
 }
 
-bool ClassLinker::LoadClass(const char* descriptor, Class* klass) {
+bool ClassLinker::LoadClass(const StringPiece& descriptor, Class* klass) {
   const RawDexFile* raw = klass->GetDexFile()->GetRaw();
   const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
   if (class_def == NULL) {
@@ -346,7 +334,7 @@
   }
 }
 
-ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const char* descriptor) {
+ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) {
   for (size_t i = 0; i != class_path_.size(); ++i) {
     DexFile* dex_file = class_path_[i];
     const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor);
@@ -408,13 +396,13 @@
 
 bool ClassLinker::InsertClass(Class* klass) {
   // TODO: acquire classes_lock_
-  const char* key = klass->GetDescriptor().data();
+  const StringPiece& key = klass->GetDescriptor();
   bool success = classes_.insert(std::make_pair(key, klass)).second;
   // TODO: release classes_lock_
   return success;
 }
 
-Class* ClassLinker::LookupClass(const char* descriptor, Object* class_loader) {
+Class* ClassLinker::LookupClass(const StringPiece& descriptor, Object* class_loader) {
   // TODO: acquire classes_lock_
   Table::iterator it = classes_.find(descriptor);
   // TODO: release classes_lock_
@@ -662,7 +650,7 @@
   if (dex_file == NULL) {
     return;
   }
-  const char* descriptor = klass->GetDescriptor().data();
+  const StringPiece& descriptor = klass->GetDescriptor();
   const RawDexFile* raw = dex_file->GetRaw();
   const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
   CHECK(class_def != NULL);
@@ -1207,7 +1195,7 @@
     JType type = static_cast<JType>(descriptor[0]);
     resolved = FindPrimitiveClass(type);
   } else {
-    resolved = FindClass(descriptor, referrer->GetClassLoader(), NULL);
+    resolved = FindClass(descriptor, referrer->GetClassLoader());
   }
   if (resolved != NULL) {
     Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
diff --git a/src/class_linker.h b/src/class_linker.h
index e4c5ff9..7f85da5 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -26,15 +26,14 @@
   Method* AllocMethod();
 
   // Finds a class by its descriptor name.
-  Class* FindClass(const char* descriptor,
-                   Object* class_loader,
-                   DexFile* dex_file);
+  Class* FindClass(const StringPiece& descriptor,
+                   Object* class_loader);
 
-  Class* FindSystemClass(const char* descriptor) {
-    return FindClass(descriptor, NULL, NULL);
+  Class* FindSystemClass(const StringPiece& descriptor) {
+    return FindClass(descriptor, NULL);
   }
 
-  bool LoadClass(const char* descriptor, Class* klass);
+  bool LoadClass(const StringPiece& descriptor, Class* klass);
 
   bool LoadClass(const RawDexFile::ClassDef& class_def, Class* klass);
 
@@ -42,7 +41,7 @@
 
   bool InitializeClass(Class* klass);
 
-  Class* LookupClass(const char* descriptor, Object* class_loader);
+  Class* LookupClass(const StringPiece& descriptor, Object* class_loader);
 
   Class* ResolveClass(const Class* referring, uint32_t class_idx);
 
@@ -50,7 +49,7 @@
 
   typedef std::pair<DexFile*, const RawDexFile::ClassDef*> ClassPathEntry;
 
-  ClassPathEntry FindInClassPath(const char* descriptor);
+  ClassPathEntry FindInClassPath(const StringPiece& descriptor);
 
   void AppendToClassPath(DexFile* dex_file);
 
@@ -106,7 +105,7 @@
   std::vector<DexFile*> class_path_;
 
   // TODO: multimap
-  typedef std::map<const char*, Class*, CStringLt> Table;
+  typedef std::map<const StringPiece, Class*> Table;
 
   Table classes_;
 
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index bbe6ebc..251b6cb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -50,7 +50,7 @@
   scoped_ptr<ClassLinker> linker(ClassLinker::Create());
   linker->AppendToClassPath(dex.get());
 
-  Class* JavaLangObject = linker->FindClass("Ljava/lang/Object;", NULL, dex.get());
+  Class* JavaLangObject = linker->FindClass("Ljava/lang/Object;", NULL);
   ASSERT_TRUE(JavaLangObject != NULL);
   ASSERT_TRUE(JavaLangObject->GetClass() != NULL);
   ASSERT_EQ(JavaLangObject->GetClass(), JavaLangObject->GetClass()->GetClass());
@@ -72,7 +72,7 @@
   EXPECT_EQ(0U, JavaLangObject->NumInstanceFields());
   EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
 
-  Class* MyClass = linker->FindClass("LMyClass;", NULL, dex.get());
+  Class* MyClass = linker->FindClass("LMyClass;", NULL);
   ASSERT_TRUE(MyClass != NULL);
   ASSERT_TRUE(MyClass->GetClass() != NULL);
   ASSERT_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
diff --git a/src/dex_file.h b/src/dex_file.h
index d11b3b5..911d3ea 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -40,7 +40,7 @@
     return num_methods_;
   }
 
-  bool HasClass(const char* descriptor) {
+  bool HasClass(const StringPiece& descriptor) {
     return raw_->FindClassDef(descriptor) != NULL;
   }
 
diff --git a/src/object.cc b/src/object.cc
index f5792fc..c2c09ca 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -6,17 +6,17 @@
 #include "src/dex_file.h"
 #include "src/raw_dex_file.h"
 
-#include <string.h>
+#include <algorithm>
 
 namespace art {
 
-bool Class::IsInSamePackage(const char* descriptor1, const char* descriptor2) {
+bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
   size_t i = 0;
   while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
     ++i;
   }
-  if (strrchr(descriptor1 + i, '/') != NULL ||
-      strrchr(descriptor2 + i, '/') != NULL ) {
+  if (descriptor1.find('/', i) != StringPiece::npos ||
+      descriptor2.find('/', i) != StringPiece::npos) {
     return false;
   } else {
     return true;
@@ -24,10 +24,10 @@
 }
 
 #if 0
-bool Class::IsInSamePackage(const char* descriptor1, const char* descriptor2) {
+bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
   size_t size = std::min(descriptor1.size(), descriptor2.size());
-  std::pair<const char*, const char*> pos;
-  pos = std::mismatch(descriptor1.data(), size, descriptor2.data());
+  std::pair<StringPiece::const_iterator, StringPiece::const_iterator> pos;
+  pos = std::mismatch(descriptor1.begin(), descriptor1.begin() + size, descriptor2.begin());
   return !(*(pos.second).rfind('/') != npos && descriptor2.rfind('/') != npos);
 }
 #endif
@@ -50,8 +50,7 @@
     klass2 = klass2->GetComponentType();
   }
   // Compare the package part of the descriptor string.
-  return IsInSamePackage(klass1->descriptor_.data(),
-                         klass2->descriptor_.data());
+  return IsInSamePackage(klass1->descriptor_, klass2->descriptor_);
 }
 
 uint32_t Method::NumArgRegisters() {
diff --git a/src/object.h b/src/object.h
index cd57460..aec8c34 100644
--- a/src/object.h
+++ b/src/object.h
@@ -507,7 +507,7 @@
   // Returns true if this class is in the same packages as that class.
   bool IsInSamePackage(const Class* that) const;
 
-  static bool IsInSamePackage(const char* descriptor1, const char* descriptor2);
+  static bool IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2);
 
   // Returns true if this class represents an array class.
   bool IsArray() const {
diff --git a/src/object_test.cc b/src/object_test.cc
index b00e123..c138854 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -43,16 +43,16 @@
   ASSERT_EQ(4U, klass->NumVirtualMethods());
 
   Method* m1 = klass->GetVirtualMethod(0);
-  ASSERT_STREQ("m1", m1->GetName().data());
+  ASSERT_EQ("m1", m1->GetName());
 
   Method* m2 = klass->GetVirtualMethod(1);
-  ASSERT_STREQ("m2", m2->GetName().data());
+  ASSERT_EQ("m2", m2->GetName());
 
   Method* m3 = klass->GetVirtualMethod(2);
-  ASSERT_STREQ("m3", m3->GetName().data());
+  ASSERT_EQ("m3", m3->GetName());
 
   Method* m4 = klass->GetVirtualMethod(3);
-  ASSERT_STREQ("m4", m4->GetName().data());
+  ASSERT_EQ("m4", m4->GetName());
 
   EXPECT_TRUE(m1->HasSameReturnType(m2));
   EXPECT_TRUE(m2->HasSameReturnType(m1));
@@ -103,22 +103,22 @@
   ASSERT_TRUE(result2);
 
   Method* m1_1 = klass1->GetVirtualMethod(0);
-  ASSERT_STREQ("m1", m1_1->GetName().data());
+  ASSERT_EQ("m1", m1_1->GetName());
   Method* m2_1 = klass1->GetVirtualMethod(1);
-  ASSERT_STREQ("m2", m2_1->GetName().data());
+  ASSERT_EQ("m2", m2_1->GetName());
   Method* m3_1 = klass1->GetVirtualMethod(2);
-  ASSERT_STREQ("m3", m3_1->GetName().data());
+  ASSERT_EQ("m3", m3_1->GetName());
   Method* m4_1 = klass1->GetVirtualMethod(3);
-  ASSERT_STREQ("m4", m4_1->GetName().data());
+  ASSERT_EQ("m4", m4_1->GetName());
 
   Method* m1_2 = klass2->GetVirtualMethod(0);
-  ASSERT_STREQ("m1", m1_2->GetName().data());
+  ASSERT_EQ("m1", m1_2->GetName());
   Method* m2_2 = klass2->GetVirtualMethod(1);
-  ASSERT_STREQ("m2", m2_2->GetName().data());
+  ASSERT_EQ("m2", m2_2->GetName());
   Method* m3_2 = klass2->GetVirtualMethod(2);
-  ASSERT_STREQ("m3", m3_2->GetName().data());
+  ASSERT_EQ("m3", m3_2->GetName());
   Method* m4_2 = klass2->GetVirtualMethod(3);
-  ASSERT_STREQ("m4", m4_2->GetName().data());
+  ASSERT_EQ("m4", m4_2->GetName());
 
   EXPECT_TRUE(m1_1->HasSameNameAndPrototype(m1_2));
   EXPECT_TRUE(m1_2->HasSameNameAndPrototype(m1_1));
diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc
index caa159a..9960aea 100644
--- a/src/raw_dex_file.cc
+++ b/src/raw_dex_file.cc
@@ -154,7 +154,7 @@
   }
 }
 
-const RawDexFile::ClassDef* RawDexFile::FindClassDef(const char* descriptor) const {
+const RawDexFile::ClassDef* RawDexFile::FindClassDef(const StringPiece& descriptor) const {
   CHECK(descriptor != NULL);
   Index::const_iterator it = index_.find(descriptor);
   if (it == index_.end()) {
diff --git a/src/raw_dex_file.h b/src/raw_dex_file.h
index 6f8a581..f47b982 100644
--- a/src/raw_dex_file.h
+++ b/src/raw_dex_file.h
@@ -7,6 +7,7 @@
 #include "src/leb128.h"
 #include "src/logging.h"
 #include "src/scoped_ptr.h"
+#include "src/stringpiece.h"
 #include "src/strutil.h"
 
 #include <map>
@@ -227,7 +228,7 @@
   }
 
   // Looks up a class definition by its class descriptor.
-  const ClassDef* FindClassDef(const char* descriptor) const;
+  const ClassDef* FindClassDef(const StringPiece& descriptor) const;
 
   // Returns the number of string identifiers in the .dex file.
   size_t NumStringIds() const {
@@ -467,7 +468,7 @@
   bool IsMagicValid();
 
   // The index of descriptors to class definitions.
-  typedef std::map<const char*, const RawDexFile::ClassDef*, CStringLt> Index;
+  typedef std::map<const StringPiece, const RawDexFile::ClassDef*> Index;
   Index index_;
 
   // The base address of the memory mapping.
diff --git a/src/stringpiece.cc b/src/stringpiece.cc
index 4b1ef7b..9927309 100644
--- a/src/stringpiece.cc
+++ b/src/stringpiece.cc
@@ -34,7 +34,7 @@
   return ret;
 }
 
-int StringPiece::find(const StringPiece& s, size_type pos) const {
+StringPiece::size_type StringPiece::find(const StringPiece& s, size_type pos) const {
   if (length_ < 0 || pos > static_cast<size_type>(length_))
     return npos;
 
@@ -53,7 +53,7 @@
   return r;
 }
 
-int StringPiece::find(char c, size_type pos) const {
+StringPiece::size_type StringPiece::find(char c, size_type pos) const {
   if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
     return npos;
   }
@@ -61,7 +61,7 @@
   return result != ptr_ + length_ ? result - ptr_ : npos;
 }
 
-int StringPiece::rfind(const StringPiece& s, size_type pos) const {
+StringPiece::size_type StringPiece::rfind(const StringPiece& s, size_type pos) const {
   if (length_ < s.length_) return npos;
   const size_t ulen = length_;
   if (s.length_ == 0) return std::min(ulen, pos);
@@ -71,7 +71,7 @@
   return result != last ? result - ptr_ : npos;
 }
 
-int StringPiece::rfind(char c, size_type pos) const {
+StringPiece::size_type StringPiece::rfind(char c, size_type pos) const {
   if (length_ <= 0) return npos;
   for (int i = std::min(pos, static_cast<size_type>(length_ - 1));
        i >= 0; --i) {
diff --git a/src/stringpiece.h b/src/stringpiece.h
index 6a5c60b..249b041 100644
--- a/src/stringpiece.h
+++ b/src/stringpiece.h
@@ -143,10 +143,10 @@
 
   int copy(char* buf, size_type n, size_type pos = 0) const;
 
-  int find(const StringPiece& s, size_type pos = 0) const;
-  int find(char c, size_type pos = 0) const;
-  int rfind(const StringPiece& s, size_type pos = npos) const;
-  int rfind(char c, size_type pos = npos) const;
+  size_type find(const StringPiece& s, size_type pos = 0) const;
+  size_type find(char c, size_type pos = 0) const;
+  size_type rfind(const StringPiece& s, size_type pos = npos) const;
+  size_type rfind(char c, size_type pos = npos) const;
 
   StringPiece substr(size_type pos, size_type n = npos) const;
 };