Merge "Move jdwpspy from development to art (2 of 2)" into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 266c1f0..9e4a76d 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1714,6 +1714,26 @@
   return NULL;
 }
 
+void ClassLinker::LookupClasses(const std::string& descriptor, std::vector<Class*>& classes) {
+  classes.clear();
+  size_t hash = StringPieceHash()(descriptor);
+  MutexLock mu(classes_lock_);
+  typedef Table::const_iterator It;  // TODO: C++0x auto
+  // TODO: determine if its better to search classes_ or image_classes_ first
+  for (It it = classes_.find(hash), end = classes_.end(); it != end; ++it) {
+    Class* c = it->second;
+    if (c->GetDescriptor()->Equals(descriptor)) {
+      classes.push_back(c);
+    }
+  }
+  for (It it = image_classes_.find(hash), end = image_classes_.end(); it != end; ++it) {
+    Class* c = it->second;
+    if (c->GetDescriptor()->Equals(descriptor)) {
+      classes.push_back(c);
+    }
+  }
+}
+
 void ClassLinker::VerifyClass(Class* klass) {
   if (klass->IsVerified()) {
     return;
diff --git a/src/class_linker.h b/src/class_linker.h
index d212c59..e408dbb 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -68,6 +68,9 @@
   // by the given 'class_loader'.
   Class* LookupClass(const std::string& descriptor, const ClassLoader* class_loader);
 
+  // Finds all the classes with the given descriptor, regardless of ClassLoader.
+  void LookupClasses(const std::string& descriptor, std::vector<Class*>& classes);
+
   Class* FindPrimitiveClass(char type);
 
   // General class unloading is not supported, this is used to prune
diff --git a/src/debugger.cc b/src/debugger.cc
index 613e27e..5b8c32c 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -471,8 +471,8 @@
 }
 
 uint32_t Dbg::GetAccessFlags(JDWP::RefTypeId id) {
-  UNIMPLEMENTED(FATAL);
-  return 0;
+  Class* c = gRegistry->Get<Class*>(id);
+  return c->GetAccessFlags() & kAccJavaFlagsMask;
 }
 
 bool Dbg::IsInterface(JDWP::RefTypeId classId) {
@@ -512,7 +512,7 @@
   UNIMPLEMENTED(FATAL);
 }
 
-void Dbg::GetClassInfo(JDWP::RefTypeId classId, uint8_t* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
+void Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
   Class* c = gRegistry->Get<Class*>(classId);
   if (c->IsArrayClass()) {
     *pStatus = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
@@ -531,12 +531,16 @@
   }
 }
 
-bool Dbg::FindLoadedClassBySignature(const char* classDescriptor, JDWP::RefTypeId* pRefTypeId) {
-  UNIMPLEMENTED(FATAL);
-  return false;
+void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
+  std::vector<Class*> classes;
+  Runtime::Current()->GetClassLinker()->LookupClasses(descriptor, classes);
+  ids.clear();
+  for (size_t i = 0; i < classes.size(); ++i) {
+    ids.push_back(gRegistry->Add(classes[i]));
+  }
 }
 
-void Dbg::GetObjectType(JDWP::ObjectId objectId, uint8_t* pRefTypeTag, JDWP::RefTypeId* pRefTypeId) {
+void Dbg::GetObjectType(JDWP::ObjectId objectId, JDWP::JdwpTypeTag* pRefTypeTag, JDWP::RefTypeId* pRefTypeId) {
   Object* o = gRegistry->Get<Object*>(objectId);
   if (o->GetClass()->IsArrayClass()) {
     *pRefTypeTag = JDWP::TT_ARRAY;
@@ -1017,12 +1021,12 @@
   }
 }
 
-void Dbg::GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply) {
-  UNIMPLEMENTED(FATAL);
+void Dbg::GetStaticFieldValue(JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply) {
+  GetFieldValue(0, fieldId, pReply);
 }
 
-void Dbg::SetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, uint64_t rawValue, int width) {
-  UNIMPLEMENTED(FATAL);
+void Dbg::SetStaticFieldValue(JDWP::FieldId fieldId, uint64_t value, int width) {
+  SetFieldValue(0, fieldId, value, width);
 }
 
 std::string Dbg::StringToUtf8(JDWP::ObjectId strId) {
diff --git a/src/debugger.h b/src/debugger.h
index 8cbfeea..3f0f7f6 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -133,9 +133,9 @@
   static bool IsInterface(JDWP::RefTypeId id);
   static void GetClassList(uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
   static void GetVisibleClassList(JDWP::ObjectId classLoaderId, uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
-  static void GetClassInfo(JDWP::RefTypeId classId, uint8_t* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
-  static bool FindLoadedClassBySignature(const char* classDescriptor, JDWP::RefTypeId* pRefTypeId);
-  static void GetObjectType(JDWP::ObjectId objectId, uint8_t* pRefTypeTag, JDWP::RefTypeId* pRefTypeId);
+  static void GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
+  static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids);
+  static void GetObjectType(JDWP::ObjectId objectId, JDWP::JdwpTypeTag* pRefTypeTag, JDWP::RefTypeId* pRefTypeId);
   static uint8_t GetClassObjectType(JDWP::RefTypeId refTypeId);
   static std::string GetSignature(JDWP::RefTypeId refTypeId);
   static bool GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file);
@@ -168,8 +168,8 @@
   static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId fieldId);
   static void GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
   static void SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, uint64_t value, int width);
-  static void GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
-  static void SetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, uint64_t rawValue, int width);
+  static void GetStaticFieldValue(JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
+  static void SetStaticFieldValue(JDWP::FieldId fieldId, uint64_t value, int width);
 
   static std::string StringToUtf8(JDWP::ObjectId strId);
 
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index 65b645d..ad02f64 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -198,34 +198,19 @@
   char* classDescriptor = ReadNewUtf8String(&buf, &strLen);
   LOG(VERBOSE) << "  Req for class by signature '" << classDescriptor << "'";
 
-  /*
-   * TODO: if a class with the same name has been loaded multiple times
-   * (by different class loaders), we're supposed to return each of them.
-   *
-   * NOTE: this may mangle "className".
-   */
-  uint32_t numClasses;
-  RefTypeId refTypeId;
-  if (!Dbg::FindLoadedClassBySignature(classDescriptor, &refTypeId)) {
-    /* not currently loaded */
-    LOG(VERBOSE) << "    --> no match!";
-    numClasses = 0;
-  } else {
-    /* just the one */
-    numClasses = 1;
-  }
+  std::vector<RefTypeId> ids;
+  Dbg::FindLoadedClassBySignature(classDescriptor, ids);
 
-  expandBufAdd4BE(pReply, numClasses);
+  expandBufAdd4BE(pReply, ids.size());
 
-  if (numClasses > 0) {
-    uint8_t typeTag;
+  for (size_t i = 0; i < ids.size(); ++i) {
+    // Get class vs. interface and status flags.
+    JDWP::JdwpTypeTag typeTag;
     uint32_t status;
-
-    /* get class vs. interface and status flags */
-    Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL);
+    Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL);
 
     expandBufAdd1(pReply, typeTag);
-    expandBufAddRefTypeId(pReply, refTypeId);
+    expandBufAddRefTypeId(pReply, ids[i]);
     expandBufAdd4BE(pReply, status);
   }
 
@@ -449,7 +434,7 @@
 
   for (uint32_t i = 0; i < numClasses; i++) {
     static const char genericSignature[1] = "";
-    uint8_t refTypeTag;
+    JDWP::JdwpTypeTag refTypeTag;
     std::string descriptor;
     uint32_t status;
 
@@ -495,7 +480,7 @@
  * Get values from static fields in a reference type.
  */
 static JdwpError handleRT_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
-  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  ReadRefTypeId(&buf); // We don't need this, but we need to skip over it in the request.
   uint32_t numFields = Read4BE(&buf);
 
   LOG(VERBOSE) << "  RT_GetValues " << numFields << ":";
@@ -503,7 +488,7 @@
   expandBufAdd4BE(pReply, numFields);
   for (uint32_t i = 0; i < numFields; i++) {
     FieldId fieldId = ReadFieldId(&buf);
-    Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
+    Dbg::GetStaticFieldValue(fieldId, pReply);
   }
 
   return ERR_NONE;
@@ -529,7 +514,7 @@
   RefTypeId refTypeId = ReadRefTypeId(&buf);
 
   /* get status flags */
-  uint8_t typeTag;
+  JDWP::JdwpTypeTag typeTag;
   uint32_t status;
   Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL);
   expandBufAdd4BE(pReply, status);
@@ -662,7 +647,7 @@
     uint64_t value = jdwpReadValue(&buf, width);
 
     LOG(VERBOSE) << StringPrintf("    --> field=%x tag=%c -> %lld", fieldId, fieldTag, value);
-    Dbg::SetStaticFieldValue(classId, fieldId, value, width);
+    Dbg::SetStaticFieldValue(fieldId, value, width);
   }
 
   return ERR_NONE;
@@ -764,7 +749,7 @@
   ObjectId objectId = ReadObjectId(&buf);
   LOG(VERBOSE) << StringPrintf("  Req for type of objectId=0x%llx", objectId);
 
-  uint8_t refTypeTag;
+  JDWP::JdwpTypeTag refTypeTag;
   RefTypeId typeId;
   Dbg::GetObjectType(objectId, &refTypeTag, &typeId);