summaryrefslogtreecommitdiffstats
path: root/runtime/jdwp
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2014-03-21 17:44:46 +0100
committerSebastien Hertz <shertz@google.com>2014-03-26 11:46:43 +0100
commit4d25df3f76f864b7629ac8c0046d46997f293d8d (patch)
tree31840831d8c81d06ffd575fdb0adc8403cd8dbb1 /runtime/jdwp
parent909f133bc938928a2403baccc983701cb9ebb17f (diff)
downloadart-4d25df3f76f864b7629ac8c0046d46997f293d8d.zip
art-4d25df3f76f864b7629ac8c0046d46997f293d8d.tar.gz
art-4d25df3f76f864b7629ac8c0046d46997f293d8d.tar.bz2
Refactor deoptimization support in debugger
This CL prepares breakpoint support for inlined methods where we'll have to deoptimize everything. We move deoptimization-related information to Dbg class only (deoptimization request queue, full deoptimization event count and deoptimization lock). We replace MethodInstrumentionRequest by DeoptimizationRequest. This is used to know which kind of deoptimization is required for a particular event. It also simplifies lock ordering a bit during event setup: we no longer need to hold the deoptimization lock while holding the breakpoint lock. Moreover, the deoptimization lock should be held only after the event list lock. Bug: 12187616 Change-Id: Iff13f004adaeb25e5d609238bacce0b9720510e6
Diffstat (limited to 'runtime/jdwp')
-rw-r--r--runtime/jdwp/jdwp.h4
-rw-r--r--runtime/jdwp/jdwp_event.cc41
-rw-r--r--runtime/jdwp/jdwp_main.cc1
3 files changed, 19 insertions, 27 deletions
diff --git a/runtime/jdwp/jdwp.h b/runtime/jdwp/jdwp.h
index 4c17c96..66ebb96 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -335,12 +335,10 @@ struct JdwpState {
AtomicInteger event_serial_;
// Linked list of events requested by the debugger (breakpoints, class prep, etc).
- Mutex event_list_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ Mutex event_list_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_BEFORE(Locks::breakpoint_lock_);
JdwpEvent* event_list_ GUARDED_BY(event_list_lock_);
size_t event_list_size_ GUARDED_BY(event_list_lock_); // Number of elements in event_list_.
- size_t full_deoptimization_requests_ GUARDED_BY(event_list_lock_); // Number of events requiring
- // full deoptimization.
// Used to synchronize suspension of the event thread (to avoid receiving "resume"
// events before the thread has finished suspending itself).
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index 427350e..9b3ea2e 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -163,11 +163,12 @@ JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
* If one or more "break"-type mods are used, register them with
* the interpreter.
*/
+ DeoptimizationRequest req;
for (int i = 0; i < pEvent->modCount; i++) {
const JdwpEventMod* pMod = &pEvent->mods[i];
if (pMod->modKind == MK_LOCATION_ONLY) {
/* should only be for Breakpoint, Step, and Exception */
- Dbg::WatchLocation(&pMod->locationOnly.loc);
+ Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
} else if (pMod->modKind == MK_STEP) {
/* should only be for EK_SINGLE_STEP; should only be one */
JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
@@ -181,6 +182,11 @@ JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
dumpEvent(pEvent); /* TODO - need for field watches */
}
}
+ if (NeedsFullDeoptimization(pEvent->eventKind)) {
+ CHECK_EQ(req.kind, DeoptimizationRequest::kNothing);
+ CHECK(req.method == nullptr);
+ req.kind = DeoptimizationRequest::kFullDeoptimization;
+ }
{
/*
@@ -193,19 +199,11 @@ JdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
}
event_list_ = pEvent;
++event_list_size_;
-
- /**
- * Do we need to enable full deoptimization ?
- */
- if (NeedsFullDeoptimization(pEvent->eventKind)) {
- if (full_deoptimization_requests_ == 0) {
- // This is the first event that needs full deoptimization: enable it.
- Dbg::EnableFullDeoptimization();
- }
- ++full_deoptimization_requests_;
- }
}
+ // TODO we can do better job here since we should process only one request: the one we just
+ // created.
+ Dbg::RequestDeoptimization(req);
Dbg::ManageDeoptimization();
return ERR_NONE;
@@ -238,31 +236,28 @@ void JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
/*
* Unhook us from the interpreter, if necessary.
*/
+ DeoptimizationRequest req;
for (int i = 0; i < pEvent->modCount; i++) {
JdwpEventMod* pMod = &pEvent->mods[i];
if (pMod->modKind == MK_LOCATION_ONLY) {
/* should only be for Breakpoint, Step, and Exception */
- Dbg::UnwatchLocation(&pMod->locationOnly.loc);
+ Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
}
if (pMod->modKind == MK_STEP) {
/* should only be for EK_SINGLE_STEP; should only be one */
Dbg::UnconfigureStep(pMod->step.threadId);
}
}
+ if (NeedsFullDeoptimization(pEvent->eventKind)) {
+ CHECK_EQ(req.kind, DeoptimizationRequest::kNothing);
+ CHECK(req.method == nullptr);
+ req.kind = DeoptimizationRequest::kFullUndeoptimization;
+ }
--event_list_size_;
CHECK(event_list_size_ != 0 || event_list_ == NULL);
- /**
- * Can we disable full deoptimization ?
- */
- if (NeedsFullDeoptimization(pEvent->eventKind)) {
- --full_deoptimization_requests_;
- if (full_deoptimization_requests_ == 0) {
- // We no longer need full deoptimization.
- Dbg::DisableFullDeoptimization();
- }
- }
+ Dbg::RequestDeoptimization(req);
}
/*
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index 77c963f..5fc0228 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -215,7 +215,6 @@ JdwpState::JdwpState(const JdwpOptions* options)
event_list_lock_("JDWP event list lock", kJdwpEventListLock),
event_list_(NULL),
event_list_size_(0),
- full_deoptimization_requests_(0),
event_thread_lock_("JDWP event thread lock"),
event_thread_cond_("JDWP event thread condition variable", event_thread_lock_),
event_thread_id_(0),