From 479fc1ecc12fa6560ca90d841c4d5174fb346618 Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Fri, 4 Apr 2014 17:51:34 +0200 Subject: Support field watchpoint in interpreter We report field read/write events to instrumentation from the interpreter. This allows it to send JDWP field access and field modification events to debugger. This completes CL https://android-review.googlesource.com/90390. We also fix the JDWP FieldOnly modifier by introducing ModBasket.fieldTypeID. We incorrectly used ModBasket.classId which is actually dedicated to ClassOnly modifier based on thread's location's class id. Finally, we now enable canWatchFieldModification and canWatchFieldAccess JDWP capabilities so a debugger can request these events to be reported. Bug: 8267708 Change-Id: I987852ad47abb27b2f7e78544a8189c7a4e2f462 --- runtime/jdwp/jdwp_event.cc | 13 +++++++++---- runtime/jdwp/jdwp_handler.cc | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'runtime/jdwp') diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc index adc1074..223b7a1 100644 --- a/runtime/jdwp/jdwp_event.cc +++ b/runtime/jdwp/jdwp_event.cc @@ -108,7 +108,7 @@ namespace JDWP { */ struct ModBasket { ModBasket() : pLoc(NULL), threadId(0), classId(0), excepClassId(0), - caught(false), field(0), thisPtr(0) { } + caught(false), fieldTypeID(0), fieldId(0), thisPtr(0) { } const JdwpLocation* pLoc; /* LocationOnly */ std::string className; /* ClassMatch/ClassExclude */ @@ -116,7 +116,8 @@ struct ModBasket { RefTypeId classId; /* ClassOnly */ RefTypeId excepClassId; /* ExceptionOnly */ bool caught; /* ExceptionOnly */ - FieldId field; /* FieldOnly */ + RefTypeId fieldTypeID; /* FieldOnly */ + FieldId fieldId; /* FieldOnly */ ObjectId thisPtr; /* InstanceOnly */ /* nothing for StepOnly -- handled differently */ }; @@ -457,7 +458,10 @@ static bool ModsMatch(JdwpEvent* pEvent, ModBasket* basket) } break; case MK_FIELD_ONLY: - if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) { + if (pMod->fieldOnly.fieldId != basket->fieldId) { + return false; + } + if (!Dbg::MatchType(basket->fieldTypeID, pMod->fieldOnly.refTypeId)) { return false; } break; @@ -848,7 +852,8 @@ bool JdwpState::PostFieldEvent(const JdwpLocation* pLoc, RefTypeId typeId, Field basket.thisPtr = thisPtr; basket.threadId = Dbg::GetThreadSelfId(); basket.className = Dbg::GetClassName(pLoc->class_id); - basket.field = fieldId; + basket.fieldTypeID = typeId; + basket.fieldId = fieldId; if (InvokeInProgress()) { VLOG(jdwp) << "Not posting field event during invoke"; diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index 8ef375b..4843c2b 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -354,8 +354,8 @@ static JdwpError VM_DisposeObjects(JdwpState*, Request& request, ExpandBuf*) static JdwpError VM_Capabilities(JdwpState*, Request&, ExpandBuf* reply) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - expandBufAdd1(reply, false); // canWatchFieldModification - expandBufAdd1(reply, false); // canWatchFieldAccess + expandBufAdd1(reply, true); // canWatchFieldModification + expandBufAdd1(reply, true); // canWatchFieldAccess expandBufAdd1(reply, true); // canGetBytecodes expandBufAdd1(reply, true); // canGetSyntheticAttribute expandBufAdd1(reply, true); // canGetOwnedMonitorInfo -- cgit v1.1