Merge "Fix inadvertent submission in last CL." into dalvik-dev
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 7ddae88..7253cad 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -2324,6 +2324,78 @@
}
+llvm::Value* MethodCompiler::EmitLoadDexCacheAddr(MemberOffset offset) {
+ llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
+
+ llvm::Value* dex_cache_offset_value =
+ irb_.getPtrEquivInt(offset.Int32Value());
+
+ llvm::Value* dex_cache_field_addr =
+ irb_.CreatePtrDisp(method_object_addr, dex_cache_offset_value,
+ irb_.getJObjectTy()->getPointerTo());
+
+ return irb_.CreateLoad(dex_cache_field_addr);
+}
+
+
+void MethodCompiler::
+EmitLoadDexCacheCodeAndDirectMethodFieldAddr(llvm::Value*& code_field_addr,
+ llvm::Value*& method_field_addr,
+ uint32_t method_idx) {
+ llvm::Value* cadms_dex_cache_addr =
+ EmitLoadDexCacheAddr(Method::GetDexCacheCodeAndDirectMethodsOffset());
+
+ llvm::Value* code_index_value =
+ irb_.getPtrEquivInt(CodeAndDirectMethods::CodeIndex(method_idx));
+
+ llvm::Value* method_index_value =
+ irb_.getPtrEquivInt(CodeAndDirectMethods::MethodIndex(method_idx));
+
+ // Return the field address
+ code_field_addr = EmitArrayGEP(cadms_dex_cache_addr, code_index_value,
+ irb_.getJIntTy());
+
+ method_field_addr = EmitArrayGEP(cadms_dex_cache_addr, method_index_value,
+ irb_.getJIntTy());
+}
+
+
+llvm::Value* MethodCompiler::
+EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) {
+ llvm::Value* static_storage_dex_cache_addr =
+ EmitLoadDexCacheAddr(Method::DexCacheInitializedStaticStorageOffset());
+
+ llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
+
+ return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value,
+ irb_.getJObjectTy());
+}
+
+
+llvm::Value* MethodCompiler::
+EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) {
+ llvm::Value* resolved_type_dex_cache_addr =
+ EmitLoadDexCacheAddr(Method::DexCacheResolvedTypesOffset());
+
+ llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
+
+ return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value,
+ irb_.getJObjectTy());
+}
+
+
+llvm::Value* MethodCompiler::
+EmitLoadDexCacheStringFieldAddr(uint32_t string_idx) {
+ llvm::Value* string_dex_cache_addr =
+ EmitLoadDexCacheAddr(Method::DexCacheStringsOffset());
+
+ llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx);
+
+ return EmitArrayGEP(string_dex_cache_addr, string_idx_value,
+ irb_.getJObjectTy());
+}
+
+
CompiledMethod *MethodCompiler::Compile() {
// Code generation
CreateFunction();
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index f86d740..6a6768b 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -264,6 +264,21 @@
#undef GEN_INSN_ARGS
+ // Dex cache code generation helper function
+ llvm::Value* EmitLoadDexCacheAddr(MemberOffset dex_cache_offset);
+
+ void EmitLoadDexCacheCodeAndDirectMethodFieldAddr(
+ llvm::Value*& code_addr_field_addr,
+ llvm::Value*& method_field_addr,
+ uint32_t method_idx);
+
+ llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx);
+
+ llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx);
+
+ llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx);
+
+
// Code generation helper function
llvm::Value* EmitLoadMethodObjectAddr();
diff --git a/src/debugger.cc b/src/debugger.cc
index 8c28cd9..bbdff71 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -43,6 +43,9 @@
static const size_t kMaxAllocRecordStackDepth = 16; // Max 255.
static const size_t kNumAllocRecords = 512; // Must be power of 2.
+static const uintptr_t kInvalidId = 1;
+static const Object* kInvalidObject = reinterpret_cast<Object*>(kInvalidId);
+
class ObjectRegistry {
public:
ObjectRegistry() : lock_("ObjectRegistry lock") {
@@ -70,10 +73,14 @@
}
template<typename T> T Get(JDWP::ObjectId id) {
+ if (id == 0) {
+ return NULL;
+ }
+
MutexLock mu(lock_);
typedef std::map<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
It it = map_.find(id);
- return (it != map_.end()) ? reinterpret_cast<T>(it->second) : NULL;
+ return (it != map_.end()) ? reinterpret_cast<T>(it->second) : reinterpret_cast<T>(kInvalidId);
}
void VisitRoots(Heap::RootVisitor* visitor, void* arg) {
@@ -187,6 +194,42 @@
return false;
}
+static Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status) {
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == NULL || o == kInvalidObject) {
+ status = JDWP::ERR_INVALID_OBJECT;
+ return NULL;
+ }
+ if (!o->IsArrayInstance()) {
+ status = JDWP::ERR_INVALID_ARRAY;
+ return NULL;
+ }
+ status = JDWP::ERR_NONE;
+ return o->AsArray();
+}
+
+static Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status) {
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == NULL || o == kInvalidObject) {
+ status = JDWP::ERR_INVALID_OBJECT;
+ return NULL;
+ }
+ if (!o->IsClass()) {
+ status = JDWP::ERR_INVALID_CLASS;
+ return NULL;
+ }
+ status = JDWP::ERR_NONE;
+ return o->AsClass();
+}
+
+static Thread* DecodeThread(JDWP::ObjectId threadId) {
+ Object* thread_peer = gRegistry->Get<Object*>(threadId);
+ if (thread_peer == NULL || thread_peer == kInvalidObject) {
+ return NULL;
+ }
+ return Thread::FromManagedThread(thread_peer);
+}
+
static JDWP::JdwpTag BasicTagFromDescriptor(const char* descriptor) {
// JDWP deliberately uses the descriptor characters' ASCII values for its enum.
// Note that by "basic" we mean that we don't get more specific than JT_OBJECT.
@@ -502,56 +545,26 @@
std::string Dbg::GetClassName(JDWP::RefTypeId classId) {
Object* o = gRegistry->Get<Object*>(classId);
- if (o == NULL || !o->IsClass()) {
+ if (o == NULL) {
+ return "NULL";
+ }
+ if (o == kInvalidObject) {
+ return StringPrintf("invalid object %p", reinterpret_cast<void*>(classId));
+ }
+ if (!o->IsClass()) {
return StringPrintf("non-class %p", o); // This is only used for debugging output anyway.
}
return DescriptorToName(ClassHelper(o->AsClass()).GetDescriptor());
}
-bool Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId) {
- Object* o = gRegistry->Get<Object*>(id);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(id, status);
+ if (c == NULL) {
+ return status;
}
- classObjectId = gRegistry->Add(o);
- return true;
-}
-
-static Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status) {
- Object* o = gRegistry->Get<Object*>(id);
- if (o == NULL) {
- status = JDWP::ERR_INVALID_OBJECT;
- return NULL;
- }
- if (!o->IsArrayInstance()) {
- status = JDWP::ERR_INVALID_ARRAY;
- return NULL;
- }
- status = JDWP::ERR_NONE;
- return o->AsArray();
-}
-
-// TODO: this should probably be used everywhere we're converting a RefTypeId to a Class*.
-static Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status) {
- Object* o = gRegistry->Get<Object*>(id);
- if (o == NULL) {
- status = JDWP::ERR_INVALID_OBJECT;
- return NULL;
- }
- if (!o->IsClass()) {
- status = JDWP::ERR_INVALID_CLASS;
- return NULL;
- }
- status = JDWP::ERR_NONE;
- return o->AsClass();
-}
-
-static Thread* DecodeThread(JDWP::ObjectId threadId) {
- Object* thread_peer = gRegistry->Get<Object*>(threadId);
- if (thread_peer == NULL) {
- return NULL;
- }
- return Thread::FromManagedThread(thread_peer);
+ classObjectId = gRegistry->Add(c);
+ return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId) {
@@ -569,27 +582,43 @@
return JDWP::ERR_NONE;
}
-JDWP::ObjectId Dbg::GetClassLoader(JDWP::RefTypeId id) {
+JDWP::JdwpError Dbg::GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
Object* o = gRegistry->Get<Object*>(id);
- return gRegistry->Add(o->GetClass()->GetClassLoader());
+ if (o == NULL || o == kInvalidObject) {
+ return JDWP::ERR_INVALID_OBJECT;
+ }
+ expandBufAddObjectId(pReply, gRegistry->Add(o->GetClass()->GetClassLoader()));
+ return JDWP::ERR_NONE;
}
-bool Dbg::GetAccessFlags(JDWP::RefTypeId id, uint32_t& access_flags) {
- Object* o = gRegistry->Get<Object*>(id);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(id, status);
+ if (c == NULL) {
+ return status;
}
- access_flags = o->AsClass()->GetAccessFlags() & kAccJavaFlagsMask;
- return true;
+
+ uint32_t access_flags = c->GetAccessFlags() & kAccJavaFlagsMask;
+
+ // Set ACC_SUPER; dex files don't contain this flag, but all classes are supposed to have it set.
+ // Class.getModifiers doesn't return it, but JDWP does, so we set it here.
+ access_flags |= kAccSuper;
+
+ expandBufAdd4BE(pReply, access_flags);
+
+ return JDWP::ERR_NONE;
}
-bool Dbg::IsInterface(JDWP::RefTypeId classId, bool& is_interface) {
- Object* o = gRegistry->Get<Object*>(classId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- is_interface = o->AsClass()->IsInterface();
- return true;
+
+ expandBufAdd1(pReply, c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS);
+ expandBufAddRefTypeId(pReply, classId);
+ return JDWP::ERR_NONE;
}
void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
@@ -618,13 +647,13 @@
Runtime::Current()->GetClassLinker()->VisitClasses(ClassListCreator::Visit, &clc);
}
-bool Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
- Object* o = gRegistry->Get<Object*>(classId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- Class* c = o->AsClass();
if (c->IsArrayClass()) {
*pStatus = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
*pTypeTag = JDWP::TT_ARRAY;
@@ -640,7 +669,7 @@
if (pDescriptor != NULL) {
*pDescriptor = ClassHelper(c).GetDescriptor();
}
- return true;
+ return JDWP::ERR_NONE;
}
void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
@@ -654,7 +683,7 @@
JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId objectId, JDWP::ExpandBuf* pReply) {
Object* o = gRegistry->Get<Object*>(objectId);
- if (o == NULL) {
+ if (o == NULL || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -674,9 +703,9 @@
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId refTypeId, std::string& signature) {
+JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId classId, std::string& signature) {
JDWP::JdwpError status;
- Class* c = DecodeClass(refTypeId, status);
+ Class* c = DecodeClass(classId, status);
if (c == NULL) {
return status;
}
@@ -684,13 +713,14 @@
return JDWP::ERR_NONE;
}
-bool Dbg::GetSourceFile(JDWP::RefTypeId refTypeId, std::string& result) {
- Object* o = gRegistry->Get<Object*>(refTypeId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId classId, std::string& result) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- result = ClassHelper(o->AsClass()).GetSourceFile();
- return result != NULL;
+ result = ClassHelper(c).GetSourceFile();
+ return JDWP::ERR_NONE;
}
uint8_t Dbg::GetObjectTag(JDWP::ObjectId objectId) {
@@ -822,7 +852,11 @@
ObjectArray<Object>* oa = a->AsObjectArray<Object>();
for (int i = 0; i < count; ++i) {
JDWP::ObjectId id = JDWP::ReadObjectId(&src);
- oa->Set(offset + i, gRegistry->Get<Object*>(id));
+ Object* o = gRegistry->Get<Object*>(id);
+ if (o == kInvalidObject) {
+ return JDWP::ERR_INVALID_OBJECT;
+ }
+ oa->Set(offset + i, o);
}
}
@@ -833,30 +867,38 @@
return gRegistry->Add(String::AllocFromModifiedUtf8(str.c_str()));
}
-bool Dbg::CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object) {
- Object* o = gRegistry->Get<Object*>(classId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- new_object = gRegistry->Add(o->AsClass()->AllocObject());
- return true;
+ new_object = gRegistry->Add(c->AllocObject());
+ return JDWP::ERR_NONE;
}
/*
* Used by Eclipse's "Display" view to evaluate "new byte[5]" to get "(byte[]) [0, 0, 0, 0, 0]".
*/
-bool Dbg::CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array) {
- Object* o = gRegistry->Get<Object*>(arrayTypeId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId arrayClassId, uint32_t length, JDWP::ObjectId& new_array) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(arrayClassId, status);
+ if (c == NULL) {
+ return status;
}
- new_array = gRegistry->Add(Array::Alloc(o->AsClass(), length));
- return true;
+ new_array = gRegistry->Add(Array::Alloc(c, length));
+ return JDWP::ERR_NONE;
}
bool Dbg::MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId) {
- // TODO: error handling if the RefTypeIds aren't actually Class*s.
- return gRegistry->Get<Class*>(instClassId)->InstanceOf(gRegistry->Get<Class*>(classId));
+ JDWP::JdwpError status;
+ Class* c1 = DecodeClass(instClassId, status);
+ Class* c2 = DecodeClass(classId, status);
+ if (c1 == NULL || c2 == NULL) {
+ // TODO: it doesn't seem like we can do any better here?
+ return false;
+ }
+ return c1->InstanceOf(c2);
}
static JDWP::FieldId ToFieldId(const Field* f) {
@@ -903,7 +945,7 @@
}
}
-std::string Dbg::GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId) {
+std::string Dbg::GetMethodName(JDWP::RefTypeId, JDWP::MethodId methodId) {
Method* m = FromMethodId(methodId);
return MethodHelper(m).GetName();
}
@@ -957,13 +999,13 @@
return slot;
}
-bool Dbg::OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
- Object* o = gRegistry->Get<Object*>(refTypeId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId classId, bool with_generic, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- Class* c = o->AsClass();
size_t instance_field_count = c->NumInstanceFields();
size_t static_field_count = c->NumStaticFields();
@@ -981,16 +1023,16 @@
}
expandBufAdd4BE(pReply, MangleAccessFlags(f->GetAccessFlags()));
}
- return true;
+ return JDWP::ERR_NONE;
}
-bool Dbg::OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool with_generic, JDWP::ExpandBuf* pReply) {
- Object* o = gRegistry->Get<Object*>(refTypeId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId classId, bool with_generic, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- Class* c = o->AsClass();
size_t direct_method_count = c->NumDirectMethods();
size_t virtual_method_count = c->NumVirtualMethods();
@@ -1008,24 +1050,26 @@
}
expandBufAdd4BE(pReply, MangleAccessFlags(m->GetAccessFlags()));
}
- return true;
+ return JDWP::ERR_NONE;
}
-bool Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply) {
- Object* o = gRegistry->Get<Object*>(refTypeId);
- if (o == NULL || !o->IsClass()) {
- return false;
+JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError status;
+ Class* c = DecodeClass(classId, status);
+ if (c == NULL) {
+ return status;
}
- ClassHelper kh(o->AsClass());
+
+ ClassHelper kh(c);
size_t interface_count = kh.NumInterfaces();
expandBufAdd4BE(pReply, interface_count);
for (size_t i = 0; i < interface_count; ++i) {
expandBufAddRefTypeId(pReply, gRegistry->Add(kh.GetInterface(i)));
}
- return true;
+ return JDWP::ERR_NONE;
}
-void Dbg::OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply) {
struct DebugCallbackContext {
int numItems;
JDWP::ExpandBuf* pReply;
@@ -1068,7 +1112,7 @@
JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
}
-void Dbg::OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, bool with_generic, JDWP::ExpandBuf* pReply) {
+void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId methodId, bool with_generic, JDWP::ExpandBuf* pReply) {
struct DebugCallbackContext {
JDWP::ExpandBuf* pReply;
size_t variable_count;
@@ -1201,12 +1245,12 @@
JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply) {
Object* thread = gRegistry->Get<Object*>(threadId);
- if (thread != NULL) {
+ if (thread == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
// Okay, so it's an object, but is it actually a thread?
- if (DecodeThread(threadId)) {
+ if (DecodeThread(threadId) == NULL) {
return JDWP::ERR_INVALID_THREAD;
}
diff --git a/src/debugger.h b/src/debugger.h
index d8b9800..2397b52 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -132,17 +132,17 @@
* Class, Object, Array
*/
static std::string GetClassName(JDWP::RefTypeId id);
- static bool GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId);
+ static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId);
static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId);
- static JDWP::ObjectId GetClassLoader(JDWP::RefTypeId id);
- static bool GetAccessFlags(JDWP::RefTypeId id, uint32_t& access_flags);
- static bool IsInterface(JDWP::RefTypeId classId, bool& is_interface);
+ static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply);
+ static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply);
+ static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply);
static void GetClassList(std::vector<JDWP::RefTypeId>& classes);
- static bool GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor);
+ static JDWP::JdwpError 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 JDWP::JdwpError GetReferenceType(JDWP::ObjectId objectId, JDWP::ExpandBuf* pReply);
static JDWP::JdwpError GetSignature(JDWP::RefTypeId refTypeId, std::string& signature);
- static bool GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file);
+ static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file);
static uint8_t GetObjectTag(JDWP::ObjectId objectId);
static size_t GetTagWidth(JDWP::JdwpTag tag);
@@ -151,8 +151,8 @@
static JDWP::JdwpError SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count, const uint8_t* buf);
static JDWP::ObjectId CreateString(const std::string& str);
- static bool CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object);
- static bool CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array);
+ static JDWP::JdwpError CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object);
+ static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length, JDWP::ObjectId& new_array);
static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId);
@@ -160,9 +160,9 @@
* Method and Field
*/
static std::string GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id);
- static bool OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
- static bool OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
- static bool OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
+ static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+ static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+ static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply);
static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric, JDWP::ExpandBuf* pReply);
diff --git a/src/dex_cache.h b/src/dex_cache.h
index d87d8de..f748e57 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -69,13 +69,6 @@
return GetLength() / kMax;
}
- private:
- enum TupleIndex {
- kCode = 0,
- kMethod = 1,
- kMax = 2,
- };
-
static size_t CodeIndex(uint32_t method_idx) {
return method_idx * kMax + kCode;
}
@@ -83,6 +76,13 @@
return method_idx * kMax + kMethod;
}
+ private:
+ enum TupleIndex {
+ kCode = 0,
+ kMethod = 1,
+ kMax = 2,
+ };
+
// grant friend status to ImageWriter fixup code that needs to know internal layout
friend class ImageWriter;
diff --git a/src/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
index 285caf3..ddcc217 100644
--- a/src/jdwp/jdwp_event.cc
+++ b/src/jdwp/jdwp_event.cc
@@ -839,7 +839,7 @@
if (match_count != 0) {
VLOG(jdwp) << "EVENT: " << matchList[0]->eventKind << "(" << match_count << " total) "
- << "thread=" << (void*) basket.threadId << ")";
+ << "thread=" << (void*) basket.threadId << ")";
suspendPolicy = scanSuspendPolicy(matchList, match_count);
VLOG(jdwp) << " suspendPolicy=" << suspendPolicy;
@@ -932,10 +932,10 @@
FindMatchingEvents(EK_EXCEPTION, &basket, matchList, &match_count);
if (match_count != 0) {
VLOG(jdwp) << "EVENT: " << matchList[0]->eventKind << "(" << match_count << " total)"
- << " thread=" << (void*) basket.threadId
- << " exceptId=" << (void*) exceptionId
- << " caught=" << basket.caught << ")";
- VLOG(jdwp) << " throw: " << *pThrowLoc;
+ << " thread=" << (void*) basket.threadId
+ << " exceptId=" << (void*) exceptionId
+ << " caught=" << basket.caught << ")"
+ << " throw: " << *pThrowLoc;
if (pCatchLoc->classId == 0) {
VLOG(jdwp) << " catch: (not caught)";
} else {
@@ -1012,7 +1012,7 @@
FindMatchingEvents(EK_CLASS_PREPARE, &basket, matchList, &match_count);
if (match_count != 0) {
VLOG(jdwp) << "EVENT: " << matchList[0]->eventKind << "(" << match_count << " total) "
- << "thread=" << (void*) basket.threadId << ") " << signature;
+ << "thread=" << (void*) basket.threadId << ") " << signature;
suspendPolicy = scanSuspendPolicy(matchList, match_count);
VLOG(jdwp) << " suspendPolicy=" << suspendPolicy;
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index 3f79601..9b5761a 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -204,15 +204,16 @@
for (size_t i = 0; i < ids.size(); ++i) {
// Get class vs. interface and status flags.
- JDWP::JdwpTypeTag typeTag;
- uint32_t status;
- if (!Dbg::GetClassInfo(ids[i], &typeTag, &status, NULL)) {
- return ERR_INVALID_CLASS;
+ JDWP::JdwpTypeTag type_tag;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(ids[i], &type_tag, &class_status, NULL);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd1(pReply, typeTag);
+ expandBufAdd1(pReply, type_tag);
expandBufAddRefTypeId(pReply, ids[i]);
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
}
return ERR_NONE;
@@ -419,21 +420,22 @@
for (size_t i = 0; i < classes.size(); ++i) {
static const char genericSignature[1] = "";
- JDWP::JdwpTypeTag refTypeTag;
+ JDWP::JdwpTypeTag type_tag;
std::string descriptor;
- uint32_t status;
- if (!Dbg::GetClassInfo(classes[i], &refTypeTag, &status, &descriptor)) {
- return ERR_INVALID_CLASS;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(classes[i], &type_tag, &class_status, &descriptor);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd1(pReply, refTypeTag);
+ expandBufAdd1(pReply, type_tag);
expandBufAddRefTypeId(pReply, classes[i]);
if (descriptor_and_status) {
expandBufAddUtf8String(pReply, descriptor);
if (generic) {
expandBufAddUtf8String(pReply, genericSignature);
}
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
}
}
@@ -468,17 +470,7 @@
static JdwpError handleRT_Modifiers(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- uint32_t access_flags;
- if (!Dbg::GetAccessFlags(refTypeId, access_flags)) {
- return ERR_INVALID_CLASS;
- }
-
- // Set ACC_SUPER; dex files don't contain this flag, but all classes are supposed to have it set.
- // Class.getModifiers doesn't return it, but JDWP does, so we set it here.
- access_flags |= kAccSuper;
-
- expandBufAdd4BE(pReply, access_flags);
- return ERR_NONE;
+ return Dbg::GetModifiers(refTypeId, pReply);
}
/*
@@ -505,8 +497,9 @@
static JdwpError handleRT_SourceFile(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
std::string source_file;
- if (!Dbg::GetSourceFile(refTypeId, source_file)) {
- return ERR_ABSENT_INFORMATION;
+ JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
+ if (status != ERR_NONE) {
+ return status;
}
expandBufAddUtf8String(pReply, source_file);
return ERR_NONE;
@@ -517,12 +510,13 @@
*/
static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
- JDWP::JdwpTypeTag typeTag;
- uint32_t status;
- if (!Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL)) {
- return ERR_INVALID_CLASS;
+ JDWP::JdwpTypeTag type_tag;
+ uint32_t class_status;
+ JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
+ if (status != ERR_NONE) {
+ return status;
}
- expandBufAdd4BE(pReply, status);
+ expandBufAdd4BE(pReply, class_status);
return ERR_NONE;
}
@@ -532,7 +526,7 @@
static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << StringPrintf(" Req for interfaces in %llx (%s)", refTypeId, Dbg::GetClassName(refTypeId).c_str());
- return Dbg::OutputDeclaredInterfaces(refTypeId, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
}
/*
@@ -541,8 +535,9 @@
static JdwpError handleRT_ClassObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
ObjectId classObjectId;
- if (!Dbg::GetClassObject(refTypeId, classObjectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::GetClassObject(refTypeId, classObjectId);
+ if (status != ERR_NONE) {
+ return status;
}
VLOG(jdwp) << StringPrintf(" RefTypeId %llx -> ObjectId %llx", refTypeId, classObjectId);
expandBufAddObjectId(pReply, classObjectId);
@@ -586,10 +581,7 @@
*/
static JdwpError handleRT_ClassLoader(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
-
- expandBufAddObjectId(pReply, Dbg::GetClassLoader(refTypeId));
-
- return ERR_NONE;
+ return Dbg::GetClassLoader(refTypeId, pReply);
}
static std::string Describe(const RefTypeId& refTypeId) {
@@ -605,14 +597,14 @@
static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for fields in " << Describe(refTypeId);
- return Dbg::OutputDeclaredFields(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
}
// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
static JdwpError handleRT_Fields(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for fields in " << Describe(refTypeId);
- return Dbg::OutputDeclaredFields(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
}
/*
@@ -622,14 +614,14 @@
static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for methods in " << Describe(refTypeId);
- return Dbg::OutputDeclaredMethods(refTypeId, true, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
}
// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
static JdwpError handleRT_Methods(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId refTypeId = ReadRefTypeId(&buf);
VLOG(jdwp) << " Req for methods in " << Describe(refTypeId);
- return Dbg::OutputDeclaredMethods(refTypeId, false, pReply) ? ERR_NONE : ERR_INVALID_CLASS;
+ return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
}
/*
@@ -699,8 +691,9 @@
VLOG(jdwp) << "Creating instance of " << Dbg::GetClassName(classId);
ObjectId objectId;
- if (!Dbg::CreateObject(classId, objectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::CreateObject(classId, objectId);
+ if (status != ERR_NONE) {
+ return status;
}
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
@@ -717,8 +710,9 @@
VLOG(jdwp) << "Creating array " << Dbg::GetClassName(arrayTypeId) << "[" << length << "]";
ObjectId objectId;
- if (!Dbg::CreateArrayObject(arrayTypeId, length, objectId)) {
- return ERR_INVALID_CLASS;
+ JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, objectId);
+ if (status != ERR_NONE) {
+ return status;
}
if (objectId == 0) {
return ERR_OUT_OF_MEMORY;
@@ -1440,18 +1434,8 @@
*/
static JdwpError handleCOR_ReflectedType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
RefTypeId classObjectId = ReadRefTypeId(&buf);
-
VLOG(jdwp) << StringPrintf(" Req for refTypeId for class=%llx (%s)", classObjectId, Dbg::GetClassName(classObjectId).c_str());
-
- bool is_interface;
- if (!Dbg::IsInterface(classObjectId, is_interface)) {
- return ERR_INVALID_CLASS;
- }
-
- expandBufAdd1(pReply, is_interface ? TT_INTERFACE : TT_CLASS);
- expandBufAddRefTypeId(pReply, classObjectId);
-
- return ERR_NONE;
+ return Dbg::GetReflectedType(classObjectId, pReply);
}
/*