Implement getting of 64-bit locals (double, long).
Also implement the JDWP "GetClassLoader" request, used by jswat's "classes"
command.
Also implement the JDWP "exit" request, tested with jswat's "shutdown".
Change-Id: Ic8424a332151242211d8a772721deb3199b24682
diff --git a/src/dalvik_system_VMStack.cc b/src/dalvik_system_VMStack.cc
index d87bc2b..682aed9 100644
--- a/src/dalvik_system_VMStack.cc
+++ b/src/dalvik_system_VMStack.cc
@@ -59,7 +59,7 @@
// TODO: need SmartFrame (Thread::WalkStack-like iterator).
for (Frame frame = self->GetTopOfStack(); frame.HasNext(); frame.Next()) {
Class* c = frame.GetMethod()->GetDeclaringClass();
- Object* cl = const_cast<ClassLoader*>(c->GetClassLoader());
+ Object* cl = c->GetClassLoader();
if (cl != bootstrap && cl != system) {
return AddLocalReference<jobject>(env, cl);
}
diff --git a/src/debugger.cc b/src/debugger.cc
index c95d64a..f4969dc 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -21,6 +21,7 @@
#include <set>
#include "class_linker.h"
+#include "class_loader.h"
#include "context.h"
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"
@@ -440,7 +441,7 @@
}
void Dbg::Exit(int status) {
- UNIMPLEMENTED(FATAL);
+ exit(status); // This is all dalvik did.
}
void Dbg::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
@@ -465,8 +466,8 @@
}
JDWP::ObjectId Dbg::GetClassLoader(JDWP::RefTypeId id) {
- UNIMPLEMENTED(FATAL);
- return 0;
+ Object* o = gRegistry->Get<Object*>(id);
+ return gRegistry->Add(o->GetClass()->GetClassLoader());
}
uint32_t Dbg::GetAccessFlags(JDWP::RefTypeId id) {
@@ -1208,16 +1209,16 @@
case JDWP::JT_BOOLEAN:
{
CHECK_EQ(expectedLen, 1U);
- uint32_t intVal = static_cast<uint32_t>(f.GetVReg(m, reg));
- LOG(WARNING) << "get boolean local " << reg << " = " << intVal;
+ uint32_t intVal = f.GetVReg(m, reg);
+ LOG(VERBOSE) << "get boolean local " << reg << " = " << intVal;
JDWP::Set1(buf+1, intVal != 0);
}
break;
case JDWP::JT_BYTE:
{
CHECK_EQ(expectedLen, 1U);
- uint32_t intVal = static_cast<uint32_t>(f.GetVReg(m, reg));
- LOG(WARNING) << "get byte local " << reg << " = " << intVal;
+ uint32_t intVal = f.GetVReg(m, reg);
+ LOG(VERBOSE) << "get byte local " << reg << " = " << intVal;
JDWP::Set1(buf+1, intVal);
}
break;
@@ -1225,8 +1226,8 @@
case JDWP::JT_CHAR:
{
CHECK_EQ(expectedLen, 2U);
- uint32_t intVal = static_cast<uint32_t>(f.GetVReg(m, reg));
- LOG(WARNING) << "get short/char local " << reg << " = " << intVal;
+ uint32_t intVal = f.GetVReg(m, reg);
+ LOG(VERBOSE) << "get short/char local " << reg << " = " << intVal;
JDWP::Set2BE(buf+1, intVal);
}
break;
@@ -1234,8 +1235,8 @@
case JDWP::JT_FLOAT:
{
CHECK_EQ(expectedLen, 4U);
- uint32_t intVal = static_cast<uint32_t>(f.GetVReg(m, reg));
- LOG(WARNING) << "get int/float local " << reg << " = " << intVal;
+ uint32_t intVal = f.GetVReg(m, reg);
+ LOG(VERBOSE) << "get int/float local " << reg << " = " << intVal;
JDWP::Set4BE(buf+1, intVal);
}
break;
@@ -1243,7 +1244,7 @@
{
CHECK_EQ(expectedLen, sizeof(JDWP::ObjectId));
Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
- LOG(WARNING) << "get array local " << reg << " = " << o;
+ LOG(VERBOSE) << "get array local " << reg << " = " << o;
if (o != NULL && !Heap::IsHeapAddress(o)) {
LOG(FATAL) << "reg " << reg << " expected to hold array: " << o;
}
@@ -1254,7 +1255,7 @@
{
CHECK_EQ(expectedLen, sizeof(JDWP::ObjectId));
Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
- LOG(WARNING) << "get object local " << reg << " = " << o;
+ LOG(VERBOSE) << "get object local " << reg << " = " << o;
if (o != NULL && !Heap::IsHeapAddress(o)) {
LOG(FATAL) << "reg " << reg << " expected to hold object: " << o;
}
@@ -1265,9 +1266,11 @@
case JDWP::JT_DOUBLE:
case JDWP::JT_LONG:
{
- UNIMPLEMENTED(WARNING) << "get 64-bit local " << reg;
CHECK_EQ(expectedLen, 8U);
- uint64_t longVal = 0; // memcpy(&longVal, &framePtr[reg], 8);
+ uint32_t lo = f.GetVReg(m, reg);
+ uint64_t hi = f.GetVReg(m, reg + 1);
+ uint64_t longVal = (hi << 32) | lo;
+ LOG(VERBOSE) << "get double/long local " << hi << ":" << lo << " = " << longVal;
JDWP::Set8BE(buf+1, longVal);
}
break;
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index cba037a..b85969e 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -195,7 +195,7 @@
jobject Class_getClassLoader(JNIEnv* env, jclass, jobject javaClass) {
Class* c = Decode<Class*>(env, javaClass);
- Object* result = reinterpret_cast<Object*>(const_cast<ClassLoader*>(c->GetClassLoader()));
+ Object* result = c->GetClassLoader();
return AddLocalReference<jobject>(env, result);
}
diff --git a/src/object.cc b/src/object.cc
index abf8310..3053823 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -1024,8 +1024,8 @@
return this == GetDescriptor()->GetClass();
}
-const ClassLoader* Class::GetClassLoader() const {
- return GetFieldObject<const ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
+ClassLoader* Class::GetClassLoader() const {
+ return GetFieldObject<ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
}
void Class::SetClassLoader(const ClassLoader* new_cl) {
diff --git a/src/object.h b/src/object.h
index 85542d2..82cd0a3 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1583,7 +1583,7 @@
SetField32(OFFSET_OF_OBJECT_MEMBER(Class, super_class_type_idx_), new_super_class_idx, false);
}
- const ClassLoader* GetClassLoader() const;
+ ClassLoader* GetClassLoader() const;
void SetClassLoader(const ClassLoader* new_cl);
@@ -1949,7 +1949,7 @@
String* name_; // TODO initialize
// defining class loader, or NULL for the "bootstrap" system loader
- const ClassLoader* class_loader_;
+ ClassLoader* class_loader_;
// For array classes, the component class object for instanceof/checkcast
// (for String[][][], this will be String[][]). NULL for non-array classes.
diff --git a/src/stack.cc b/src/stack.cc
index 1e1f932..9589b57 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -45,11 +45,11 @@
return *reinterpret_cast<uintptr_t*>(pc_addr);
}
-uintptr_t Frame::GetVReg(Method* method, int vreg) const {
+uint32_t Frame::GetVReg(Method* method, int vreg) const {
DCHECK(method == GetMethod());
int offset = oatVRegOffsetFromMethod(method, vreg);
byte* vreg_addr = reinterpret_cast<byte*>(sp_) + offset;
- return *reinterpret_cast<uintptr_t*>(vreg_addr);
+ return *reinterpret_cast<uint32_t*>(vreg_addr);
}
uintptr_t Frame::LoadCalleeSave(int num) const {
diff --git a/src/stack.h b/src/stack.h
index f1fb08f..680a69d 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -54,7 +54,7 @@
uintptr_t LoadCalleeSave(int num) const;
- uintptr_t GetVReg(Method* method, int vreg) const;
+ uint32_t GetVReg(Method* method, int vreg) const;
Method** GetSP() const {
return sp_;