Implement local setting.
I've also worked out how to test CreateString and CreateObject, but
not CreateArrayObject yet.
Also stop saying "cnt".
Change-Id: I26569ff6c4fa356fb91e6c22cbf8ced95094fabd
diff --git a/src/debugger.cc b/src/debugger.cc
index a858962..98d501c 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -716,13 +716,12 @@
}
JDWP::ObjectId Dbg::CreateString(const char* str) {
- UNIMPLEMENTED(FATAL);
- return 0;
+ return gRegistry->Add(String::AllocFromModifiedUtf8(str));
}
JDWP::ObjectId Dbg::CreateObject(JDWP::RefTypeId classId) {
- UNIMPLEMENTED(FATAL);
- return 0;
+ Class* c = gRegistry->Get<Class*>(classId);
+ return gRegistry->Add(c->AllocObject());
}
JDWP::ObjectId Dbg::CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length) {
@@ -1295,7 +1294,7 @@
return false;
}
-void Dbg::GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t expectedLen) {
+void Dbg::GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t width) {
Method** sp = reinterpret_cast<Method**>(frameId);
Frame f;
f.SetSP(sp);
@@ -1311,7 +1310,7 @@
switch (tag) {
case JDWP::JT_BOOLEAN:
{
- CHECK_EQ(expectedLen, 1U);
+ CHECK_EQ(width, 1U);
uint32_t intVal = f.GetVReg(m, reg);
LOG(VERBOSE) << "get boolean local " << reg << " = " << intVal;
JDWP::Set1(buf+1, intVal != 0);
@@ -1319,7 +1318,7 @@
break;
case JDWP::JT_BYTE:
{
- CHECK_EQ(expectedLen, 1U);
+ CHECK_EQ(width, 1U);
uint32_t intVal = f.GetVReg(m, reg);
LOG(VERBOSE) << "get byte local " << reg << " = " << intVal;
JDWP::Set1(buf+1, intVal);
@@ -1328,7 +1327,7 @@
case JDWP::JT_SHORT:
case JDWP::JT_CHAR:
{
- CHECK_EQ(expectedLen, 2U);
+ CHECK_EQ(width, 2U);
uint32_t intVal = f.GetVReg(m, reg);
LOG(VERBOSE) << "get short/char local " << reg << " = " << intVal;
JDWP::Set2BE(buf+1, intVal);
@@ -1337,7 +1336,7 @@
case JDWP::JT_INT:
case JDWP::JT_FLOAT:
{
- CHECK_EQ(expectedLen, 4U);
+ CHECK_EQ(width, 4U);
uint32_t intVal = f.GetVReg(m, reg);
LOG(VERBOSE) << "get int/float local " << reg << " = " << intVal;
JDWP::Set4BE(buf+1, intVal);
@@ -1345,7 +1344,7 @@
break;
case JDWP::JT_ARRAY:
{
- CHECK_EQ(expectedLen, sizeof(JDWP::ObjectId));
+ CHECK_EQ(width, sizeof(JDWP::ObjectId));
Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
LOG(VERBOSE) << "get array local " << reg << " = " << o;
if (o != NULL && !Heap::IsHeapAddress(o)) {
@@ -1356,7 +1355,7 @@
break;
case JDWP::JT_OBJECT:
{
- CHECK_EQ(expectedLen, sizeof(JDWP::ObjectId));
+ CHECK_EQ(width, sizeof(JDWP::ObjectId));
Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
LOG(VERBOSE) << "get object local " << reg << " = " << o;
if (o != NULL && !Heap::IsHeapAddress(o)) {
@@ -1369,7 +1368,7 @@
case JDWP::JT_DOUBLE:
case JDWP::JT_LONG:
{
- CHECK_EQ(expectedLen, 8U);
+ CHECK_EQ(width, 8U);
uint32_t lo = f.GetVReg(m, reg);
uint64_t hi = f.GetVReg(m, reg + 1);
uint64_t longVal = (hi << 32) | lo;
@@ -1387,7 +1386,53 @@
}
void Dbg::SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint64_t value, size_t width) {
- UNIMPLEMENTED(FATAL);
+ Method** sp = reinterpret_cast<Method**>(frameId);
+ Frame f;
+ f.SetSP(sp);
+ uint16_t reg = DemangleSlot(slot, f);
+ Method* m = f.GetMethod();
+
+ const VmapTable vmap_table(m->GetVmapTableRaw());
+ uint32_t vmap_offset;
+ if (vmap_table.IsInContext(reg, vmap_offset)) {
+ UNIMPLEMENTED(FATAL) << "don't know how to pull locals from callee save frames: " << vmap_offset;
+ }
+
+ switch (tag) {
+ case JDWP::JT_BOOLEAN:
+ case JDWP::JT_BYTE:
+ CHECK_EQ(width, 1U);
+ f.SetVReg(m, reg, static_cast<uint32_t>(value));
+ break;
+ case JDWP::JT_SHORT:
+ case JDWP::JT_CHAR:
+ CHECK_EQ(width, 2U);
+ f.SetVReg(m, reg, static_cast<uint32_t>(value));
+ break;
+ case JDWP::JT_INT:
+ case JDWP::JT_FLOAT:
+ CHECK_EQ(width, 4U);
+ f.SetVReg(m, reg, static_cast<uint32_t>(value));
+ break;
+ case JDWP::JT_ARRAY:
+ case JDWP::JT_OBJECT:
+ case JDWP::JT_STRING:
+ {
+ CHECK_EQ(width, sizeof(JDWP::ObjectId));
+ Object* o = gRegistry->Get<Object*>(static_cast<JDWP::ObjectId>(value));
+ f.SetVReg(m, reg, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(o)));
+ }
+ break;
+ case JDWP::JT_DOUBLE:
+ case JDWP::JT_LONG:
+ CHECK_EQ(width, 8U);
+ f.SetVReg(m, reg, static_cast<uint32_t>(value));
+ f.SetVReg(m, reg + 1, static_cast<uint32_t>(value >> 32));
+ break;
+ default:
+ LOG(FATAL) << "unknown tag " << tag;
+ break;
+ }
}
void Dbg::PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags) {
@@ -1640,11 +1685,11 @@
DdmSendChunk(type, bytes.size(), &bytes[0]);
}
-void Dbg::DdmSendChunkV(uint32_t type, const struct iovec* iov, int iovcnt) {
+void Dbg::DdmSendChunkV(uint32_t type, const struct iovec* iov, int iov_count) {
if (gJdwpState == NULL) {
LOG(VERBOSE) << "Debugger thread not active, ignoring DDM send: " << type;
} else {
- gJdwpState->DdmSendChunkV(type, iov, iovcnt);
+ gJdwpState->DdmSendChunkV(type, iov, iov_count);
}
}