jdwp_event.cc revision cbc5064ff05179b97b416f00ca579c55e38cd7d9
1872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
2872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Copyright (C) 2008 The Android Open Source Project
3872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
4872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * you may not use this file except in compliance with the License.
6872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * You may obtain a copy of the License at
7872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
8872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
10872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Unless required by applicable law or agreed to in writing, software
11872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See the License for the specific language governing permissions and
14872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * limitations under the License.
15872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
17872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_event.h"
18872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <stddef.h>     /* for offsetof() */
20872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <stdlib.h>
21872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <string.h>
22872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <unistd.h>
23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
24c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h"
25e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h"
2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
27e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h"
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "debugger.h"
2907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_constants.h"
3007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_expand_buf.h"
3107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h"
326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "jdwp/object_registry.h"
336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "scoped_thread_state_change.h"
34693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread-inl.h"
3507ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
36261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz#include "handle_scope-inl.h"
37261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz
38872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
39872d4ec7225444d9400d30f9027247deb91012fdElliott HughesGeneral notes:
40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
41872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe event add/remove stuff usually happens from the debugger thread,
42872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesin response to requests from the debugger, but can also happen as the
43872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesresult of an event in an arbitrary thread (e.g. an event with a "count"
44872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmod expires).  It's important to keep the event list locked when processing
45872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesevents.
46872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
47872d4ec7225444d9400d30f9027247deb91012fdElliott HughesEvent posting can happen from any thread.  The JDWP thread will not usually
48872d4ec7225444d9400d30f9027247deb91012fdElliott Hughespost anything but VM start/death, but if a JDWP request causes a class
49872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesto be loaded, the ClassPrepare event will come from the JDWP thread.
50872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
51872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
52872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe can have serialization issues when we post an event to the debugger.
53872d4ec7225444d9400d30f9027247deb91012fdElliott HughesFor example, a thread could send an "I hit a breakpoint and am suspending
54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmyself" message to the debugger.  Before it manages to suspend itself, the
55872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdebugger's response ("not interested, resume thread") arrives and is
56872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesprocessed.  We try to resume a thread that hasn't yet suspended.
57872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
58872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThis means that, after posting an event to the debugger, we need to wait
59872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfor the event thread to suspend itself (and, potentially, all other threads)
60872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore processing any additional requests from the debugger.  While doing
61872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesso we need to be aware that multiple threads may be hitting breakpoints
62872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor other events simultaneously, so we either need to wait for all of them
63872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor serialize the events with each other.
64872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
65872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe current mechanism works like this:
66872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  Event thread:
67872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
68872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     for it if it's not currently available.
69872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - Post the event to the debugger.
70872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If appropriate, suspend others and then myself.  As part of suspending
71872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     myself, release the "I am posting" token.
72872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JDWP thread:
73872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - When an event arrives, see if somebody is posting an event.  If so,
74872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     sleep until we can acquire the "I am posting an event" token.  Release
75872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     it immediately and continue processing -- the event we have already
76872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     received should not interfere with other events that haven't yet
77872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     been posted.
78872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
79872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSome care must be taken to avoid deadlock:
80872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
81872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A and thread B exit near-simultaneously, and post thread-death
82872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   events with a "suspend all" clause
83872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A gets the event token, thread B sits and waits for it
84872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A wants to suspend all other threads, but thread B is waiting
85872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   for the token and can't be suspended
86872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
87872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSo we need to mark thread B in such a way that thread A doesn't wait for it.
88872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
89872d4ec7225444d9400d30f9027247deb91012fdElliott HughesIf we just bracket the "grab event token" call with a change to VMWAIT
90872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore sleeping, the switch back to RUNNING state when we get the token
91872d4ec7225444d9400d30f9027247deb91012fdElliott Hugheswill cause thread B to suspend (remember, thread A's global suspend is
92872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstill in force, even after it releases the token).  Suspending while
93872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesholding the event token is very bad, because it prevents the JDWP thread
94872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfrom processing incoming messages.
95872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
96872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe need to change to VMWAIT state at the *start* of posting an event,
97872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesand stay there until we either finish posting the event or decide to
98872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesput ourselves to sleep.  That way we don't interfere with anyone else and
99872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdon't allow anyone else to interfere with us.
100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes*/
101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art {
103872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
104872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace JDWP {
105872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Stuff to compare against when deciding if a mod matches.  Only the
108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * values for mods valid for the event being evaluated will be filled in.
109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The rest will be zeroed.
110261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz * Must be allocated on the stack only. This is enforced by removing the
111261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz * operator new.
112872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct ModBasket {
114261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  explicit ModBasket(Thread* self)
115261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz    : hs(self), pLoc(nullptr), thread(self),
116261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      locationClass(hs.NewHandle<mirror::Class>(nullptr)),
117261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      exceptionClass(hs.NewHandle<mirror::Class>(nullptr)),
118261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      caught(false),
119261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      field(nullptr),
120261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      thisPtr(hs.NewHandle<mirror::Object>(nullptr)) { }
121261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz
122261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  StackHandleScope<3> hs;
123261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  const EventLocation*            pLoc;             /* LocationOnly */
124261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  std::string                     className;        /* ClassMatch/ClassExclude */
125261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  Thread* const                   thread;           /* ThreadOnly */
126261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  MutableHandle<mirror::Class>    locationClass;    /* ClassOnly */
127261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  MutableHandle<mirror::Class>    exceptionClass;   /* ExceptionOnly */
128261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  bool                            caught;           /* ExceptionOnly */
129261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ArtField*                       field;            /* FieldOnly */
130261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  MutableHandle<mirror::Object>   thisPtr;          /* InstanceOnly */
131872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* nothing for StepOnly -- handled differently */
132261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz
133261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz private:
134261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  DISALLOW_ALLOCATION();  // forbids allocation on the heap.
135261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  DISALLOW_IMPLICIT_CONSTRUCTORS(ModBasket);
136872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes};
137872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
138138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertzstatic bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
139f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  if (!Dbg::RequiresDeoptimization()) {
140f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz    // We don't need deoptimization for debugging.
141f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz    return false;
142f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  }
143138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  switch (eventKind) {
144138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_ENTRY:
145138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT:
146138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT_WITH_RETURN_VALUE:
1473f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_ACCESS:
1483f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_MODIFICATION:
149138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return true;
150138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      default:
151138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return false;
152138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
153138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz}
154138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
1559d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// Returns the instrumentation event the DebugInstrumentationListener must
1569d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// listen to in order to properly report the given JDWP event to the debugger.
157277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
15842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  switch (eventKind) {
15942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_BREAKPOINT:
16042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_SINGLE_STEP:
16142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kDexPcMoved;
16242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION:
16342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION_CATCH:
16442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kExceptionCaught;
16542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_ENTRY:
16642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodEntered;
16742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT:
16842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT_WITH_RETURN_VALUE:
16942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodExited;
17042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_ACCESS:
17142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldRead;
17242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_MODIFICATION:
17342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldWritten;
17442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    default:
17542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return 0;
17642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  }
17742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz}
17842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
179872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
180872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Add an event to the list.  Ordering is not important.
181872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If something prevents the event from being registered, e.g. it's a
183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * single-step request on a thread that doesn't exist, the event will
184872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * not be added to the list, and an appropriate error will be returned.
185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
186761928d24e4e7ed7776b52243eaf9095ad35f448Elliott HughesJdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
1877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent != nullptr);
1887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
1897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
190872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
19142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
19242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
19342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * If one or more "break"-type mods are used, register them with
19442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * the interpreter.
19542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
19642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
19742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      const JdwpEventMod* pMod = &pEvent->mods[i];
19942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
200033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Should only concern breakpoint, field access, field modification, step, and exception
201033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events.
202033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // However breakpoint requires specific handling. Field access, field modification and step
203033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events need full deoptimization to be reported while exception event is reported during
204033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // exception handling.
205033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
206033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
207033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
20842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      } else if (pMod->modKind == MK_STEP) {
20942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
21042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
21142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
21242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
21342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        if (status != ERR_NONE) {
21442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz          return status;
21542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        }
2162435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes      }
217872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
21842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (NeedsFullDeoptimization(pEvent->eventKind)) {
2190ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2200ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2210ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullDeoptimization);
22242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    }
22342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
22542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
22642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
22742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2280ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kRegisterForEvent);
2290ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
23042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2314d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
233138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
234138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    /*
235138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     * Add to list.
236138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     */
237138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
2387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (event_list_ != nullptr) {
239138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      pEvent->next = event_list_;
240138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      event_list_->prev = pEvent;
241138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
242138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    event_list_ = pEvent;
243138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    ++event_list_size_;
244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
245138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
246138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return ERR_NONE;
249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
250872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
251872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove an event from the list.  This will also remove the event from
253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any optimization tables, e.g. breakpoints.
254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Does not free the JdwpEvent.
256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the eventLock before calling here.
258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
259761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
2607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->prev == nullptr) {
261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* head of the list */
262f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK(event_list_ == pEvent);
263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
264f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    event_list_ = pEvent->next;
265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
266872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->prev->next = pEvent->next;
267872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
268872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
2697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->next != nullptr) {
270872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->next->prev = pEvent->prev;
2717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    pEvent->next = nullptr;
272872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
2737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  pEvent->prev = nullptr;
274872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
27542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
27642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
27742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * Unhook us from the interpreter, if necessary.
27842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
27942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
28042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
28142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      JdwpEventMod* pMod = &pEvent->mods[i];
28242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
283033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Like in RegisterEvent, we need specific handling for breakpoint only.
284033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
285033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
286033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
28742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_STEP) {
28942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
29042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::UnconfigureStep(pMod->step.threadId);
29142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
292872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
293eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    if (NeedsFullDeoptimization(pEvent->eventKind)) {
2940ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2950ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2960ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
29842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
30042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
30142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
30242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
3030ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
3040ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
30542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
3064d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
308f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  --event_list_size_;
3097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(event_list_size_ != 0 || event_list_ == nullptr);
310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
312872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
313872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove the event with the given ID from the list.
314872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
315872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
316761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEventById(uint32_t requestId) {
317138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool found = false;
318138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
319138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
320872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
321138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
322138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      if (pEvent->requestId == requestId) {
323138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        found = true;
324138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        UnregisterEvent(pEvent);
325138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        EventFree(pEvent);
326138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        break;      /* there can be only one with a given ID */
327138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      }
328872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
329872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
330872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
331138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  if (found) {
332138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    Dbg::ManageDeoptimization();
333138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  } else {
334f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
335f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // try to be extra careful and will explicitly remove one-off single-step events (using a
336f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // 'count' event modifier of 1). So the event may have already been removed as part of the
337f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // event notification (see JdwpState::CleanupMatchList).
338f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
339138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  }
340872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
342872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
343872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove all entries from the event list.
344872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
345761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterAll() {
34650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), event_list_lock_);
347872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
348f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpEvent* pEvent = event_list_;
3497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  while (pEvent != nullptr) {
350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    JdwpEvent* pNextEvent = pEvent->next;
351872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
352761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    UnregisterEvent(pEvent);
353872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    EventFree(pEvent);
354872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent = pNextEvent;
355872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
3577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  event_list_ = nullptr;
358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
361872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate a JdwpEvent struct with enough space to hold the specified
362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * number of mod records.
363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
364872d4ec7225444d9400d30f9027247deb91012fdElliott HughesJdwpEvent* EventAlloc(int numMods) {
365872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEvent* newEvent;
366872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
367872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  memset(newEvent, 0, allocSize);
369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return newEvent;
370872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
371872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
372872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
373872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free a JdwpEvent.
374872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
375872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do not call this until the event has been removed from the list.
376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
377872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesvoid EventFree(JdwpEvent* pEvent) {
3787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent == nullptr) {
379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
380872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
382872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* make sure it was removed from the list */
3837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
3847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
385f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  /* want to check state->event_list_ != pEvent */
386872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
388872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Free any hairy bits in the mods.
389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
390872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = 0; i < pEvent->modCount; i++) {
391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
392872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classMatch.classPattern);
3937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classMatch.classPattern = nullptr;
394872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
395872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
396872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classExclude.classPattern);
3977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classExclude.classPattern = nullptr;
398872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
399872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
400872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
401872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  free(pEvent);
402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
403872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
405872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Run through the list and remove any entries with an expired "count" mod
4067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * from the event list.
407872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
4087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
4097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
4107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    for (int i = 0; i < pEvent->modCount; ++i) {
411872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
412bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
413bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                   pEvent->requestId);
414761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        UnregisterEvent(pEvent);
415872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        EventFree(pEvent);
416872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        break;
417872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
418872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
419872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
420872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Match a string against a "restricted regular expression", which is just
424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
426872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ("Restricted name globbing" might have been a better term.)
427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
428761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic bool PatternMatch(const char* pattern, const std::string& target) {
429a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  size_t patLen = strlen(pattern);
430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pattern[0] == '*') {
431872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    patLen--;
432a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    if (target.size() < patLen) {
433872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      return false;
434872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
435a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
436872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else if (pattern[patLen-1] == '*') {
437a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strncmp(pattern, target.c_str(), patLen-1) == 0;
438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
439a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern, target.c_str()) == 0;
440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See if the event's mods match up with the contents of "basket".
445872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
446872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we find a Count mod before rejecting an event, we decrement it.  We
447872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * need to do this even if later mods cause us to ignore the event.
448872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
449bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
450b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEventMod* pMod = pEvent->mods;
452872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
453872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    switch (pMod->modKind) {
455872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_COUNT:
456872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK_GT(pMod->count.count, 0);
457872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pMod->count.count--;
45843207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      if (pMod->count.count > 0) {
45943207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz        return false;
46043207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      }
461872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
462872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CONDITIONAL:
463872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK(false);  // should not be getting these
464872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
465872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_THREAD_ONLY:
4666995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
468872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_ONLY:
471261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      if (!Dbg::MatchType(basket.locationClass.Get(), pMod->classOnly.refTypeId)) {
472872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
473872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
474872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
475872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_MATCH:
476bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
477872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
478872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
479872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_EXCLUDE:
481bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
482872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
483872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
484872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
485872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_LOCATION_ONLY:
4866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
488872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
489872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_EXCEPTION_ONLY:
4916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (pMod->exceptionOnly.refTypeId != 0 &&
492261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz          !Dbg::MatchType(basket.exceptionClass.Get(), pMod->exceptionOnly.refTypeId)) {
493872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
4956995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if ((basket.caught && !pMod->exceptionOnly.caught) ||
4966995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz          (!basket.caught && !pMod->exceptionOnly.uncaught)) {
497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
498872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_FIELD_ONLY:
5016995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
502872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
503872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_STEP:
5066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
508872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
509872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
510872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_INSTANCE_ONLY:
511261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz      if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr.Get())) {
512872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
513872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
514872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
515872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    default:
5167b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
517872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
518872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
521872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
522872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
523872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments while holding the event list lock. This method
5267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * is used by FindMatchingEvents below.
527872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
5287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple times for grouped
5297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * events.
530872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
531872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * DO NOT call this multiple times for the same eventKind, as Count mods are
532872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * decremented during the scan.
533872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
5357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                         std::vector<JdwpEvent*>* match_list) {
536bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
5377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
5387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      match_list->push_back(pEvent);
539872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
540872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
541872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
542872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
543872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments and return true if at least one event matches,
5467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * false otherwise.
5477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple
5497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * times for grouped events.
5507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * DO NOT call this multiple times for the same eventKind, as Count mods are
5527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * decremented during the scan.
5537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz */
5547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzbool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
5557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                   std::vector<JdwpEvent*>* match_list) {
5567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  MutexLock mu(Thread::Current(), event_list_lock_);
5577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  match_list->reserve(event_list_size_);
5587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FindMatchingEventsLocked(event_kind, basket, match_list);
5597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  return !match_list->empty();
5607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz}
5617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
5627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz/*
563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Scan through the list of matches and determine the most severe
564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspension policy.
565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
567872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpSuspendPolicy policy = SP_NONE;
568872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
5697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
5707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->suspend_policy > policy) {
5717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      policy = pEvent->suspend_policy;
572872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
573872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
574872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
575872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return policy;
576872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
577872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
578872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
579872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Three possibilities:
580872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_NONE - do nothing
581872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_EVENT_THREAD - suspend ourselves
582872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_ALL - suspend everybody except JDWP support thread
583872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
58400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
585f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
586f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_NONE) {
587872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
588872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
589872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
590f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_ALL) {
591475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    Dbg::SuspendVM();
592872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
593f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
594872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
595872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
596872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is rare but possible -- see CLASS_PREPARE handling */
59700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (thread_self_id == debug_thread_id_) {
598761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
599872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
600872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
601872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  while (true) {
603872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::SuspendSelf();
604872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
605872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /*
606872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * The JDWP thread has told us (and possibly all other threads) to
607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     */
6091558b577907b613864e98f05862543557263e864Sebastien Hertz    DebugInvokeReq* const pReq = Dbg::GetInvokeReq();
6101558b577907b613864e98f05862543557263e864Sebastien Hertz    if (pReq == nullptr) {
611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
612872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
613872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
614cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz    // Execute method.
615872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::ExecuteMethod(pReq);
616872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
617872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
618872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
61900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              ObjectId threadId) {
6217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Thread* const self = Thread::Current();
62200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->AssertThreadSuspensionIsAllowable();
6237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pReq != nullptr);
62400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  /* send request and possibly suspend ourselves */
6257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
6267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
6277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (suspend_policy != SP_NONE) {
6282bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz    AcquireJdwpTokenForEvent(threadId);
62900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
6307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  EventFinish(pReq);
631813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz  {
632813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING.
633813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    ScopedThreadStateChange stsc(self, kSuspended);
634813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    SuspendByPolicy(suspend_policy, thread_self_id);
635813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz  }
6367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromSuspendedToRunnable();
63700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
63800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
639872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Determine if there is a method invocation in progress in the current
641872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread.
642872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
643475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
644872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * state.  If set, we're in the process of invoking a method.
645872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
646761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::InvokeInProgress() {
647872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
6481558b577907b613864e98f05862543557263e864Sebastien Hertz  return pReq != nullptr;
649872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
650872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
6512bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForCommand() {
6522bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
6532bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  SetWaitForJdwpToken(debug_thread_id_);
6542bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6552bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6562bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForCommand() {
6572bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
6582bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  ClearWaitForJdwpToken();
6592bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6602bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6612bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) {
6622bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
6632bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(debug_thread_id_, threadId) << "Not expected debug thread";
6642bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  SetWaitForJdwpToken(threadId);
6652bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6662bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6672bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForEvent() {
6682bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
6692bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  ClearWaitForJdwpToken();
6702bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6712bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
672872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
673872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We need the JDWP thread to hold off on doing stuff while we post an
674872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event and then suspend ourselves.
675872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This could go to sleep waiting for another thread, so it's important
677872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that the thread be marked as VMWAIT before calling here.
678872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
6792bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::SetWaitForJdwpToken(ObjectId threadId) {
680872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  bool waited = false;
6812bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Thread* const self = Thread::Current();
6822bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(threadId, 0u);
6832bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(self->GetState(), kRunnable);
6842bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Locks::mutator_lock_->AssertNotHeld(self);
685872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
686872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is held for very brief periods; contention is unlikely */
6872bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  MutexLock mu(self, jdwp_token_lock_);
6882bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6892bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(jdwp_token_owner_thread_id_, threadId) << "Thread is already holding event thread lock";
690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
691872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
692872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If another thread is already doing stuff, wait for it.  This can
693872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * go to sleep indefinitely.
694872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
6952bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  while (jdwp_token_owner_thread_id_ != 0) {
696d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
6972bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz                               jdwp_token_owner_thread_id_, threadId);
698872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    waited = true;
6992bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz    jdwp_token_cond_.Wait(self);
700872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
701872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7022bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  if (waited || threadId != debug_thread_id_) {
703d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
704872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
7052bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_owner_thread_id_ = threadId;
706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
708872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
709872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Clear the threadId and signal anybody waiting.
710872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
7112bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ClearWaitForJdwpToken() {
712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
713872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
7142bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz   * function is called by Dbg::SuspendSelf(), and the transition back
715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * to RUNNING would confuse it.
716872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
7172bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Thread* const self = Thread::Current();
7182bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  MutexLock mu(self, jdwp_token_lock_);
719872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7202bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(jdwp_token_owner_thread_id_, 0U);
7212bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_);
722872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7232bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_owner_thread_id_ = 0;
7242bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_cond_.Signal(self);
725872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
726872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
727872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
728872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Prep an event.  Allocates storage for the message and leaves space for
729872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the header.
730872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
731872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstatic ExpandBuf* eventPrep() {
732872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = expandBufAlloc();
733872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAddSpace(pReq, kJDWPHeaderLen);
734872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return pReq;
735872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
736872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
737872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
738872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Write the header into the buffer and send the packet off to the debugger.
739872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
740872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Takes ownership of "pReq" (currently discards it).
741872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
742761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::EventFinish(ExpandBuf* pReq) {
743872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t* buf = expandBufGetBuffer(pReq);
744872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
745cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  Set4BE(buf + kJDWPHeaderSizeOffset, expandBufGetLength(pReq));
746cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  Set4BE(buf + kJDWPHeaderIdOffset, NextRequestSerial());
747cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  Set1(buf + kJDWPHeaderFlagsOffset, 0);     /* flags */
748cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  Set1(buf + kJDWPHeaderCmdSetOffset, kJDWPEventCmdSet);
749cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  Set1(buf + kJDWPHeaderCmdOffset, kJDWPEventCompositeCmd);
750872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
751761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  SendRequest(pReq);
752872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
753872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufFree(pReq);
754872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
755872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
756872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
757872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
758872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the debugger that we have finished initializing.  This is always
759872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * sent, even if the debugger hasn't requested it.
760872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
761872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This should be sent "before the main thread is started and before
762872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any application code has been executed".  The thread ID in the message
763872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * must be for the main thread.
764872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
7657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostVMStart() {
7667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
767872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId threadId = Dbg::GetThreadSelfId();
768872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "EVENT: " << EK_VM_START;
7707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
771872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
772761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  ExpandBuf* pReq = eventPrep();
7737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
7747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 1);
7757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, EK_VM_START);
7767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 0);       /* requestId */
7777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAddObjectId(pReq, threadId);
778872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
779138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
780138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
781872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* send request and possibly suspend ourselves */
78200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
783872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
784872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list,
7866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                       ObjectId thread_id)
787bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (size_t i = 0, e = match_list.size(); i < e; ++i) {
789bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    JdwpEvent* pEvent = match_list[i];
790bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
791bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz               << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
792bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
793bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  std::string thread_name;
7946995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  JdwpError error = Dbg::GetThreadName(thread_id, &thread_name);
795bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  if (error != JDWP::ERR_NONE) {
796bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    thread_name = "<unknown>";
797bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
7986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  VLOG(jdwp) << StringPrintf("  thread=%#" PRIx64, thread_id) << " " << thread_name;
7996995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz}
8006995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
8016995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzstatic void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
8026995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                             JDWP::JdwpLocation* jdwp_location)
8036995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
8046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(event_location != nullptr);
8056995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(jdwp_location != nullptr);
8066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
807bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz}
808bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
809872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A location of interest has been reached.  This handles:
811872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Breakpoint
812872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   SingleStep
813872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodEntry
814872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodExit
815872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * These four types must be grouped together in a single response.  The
816872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "eventFlags" indicates the type of event(s) that have happened.
817872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
818872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
819872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
820872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   LocationOnly (for breakpoint/step only)
821872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Step (for step only)
822872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
823872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Interesting test cases:
824872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
825872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
827872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Single-step to a line with a breakpoint.  Should get a single
828872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    event message with both events in it.
829872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
8307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
8316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                  int eventFlags, const JValue* returnValue) {
8326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
8336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc->method != nullptr);
8346995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
8356995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
836261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ModBasket basket(Thread::Current());
837872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pLoc;
838261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
839261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.thisPtr.Assign(thisPtr);
840261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass.Get());
841872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
842872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * On rare occasions we may need to execute interpreted code in the VM
844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while handling a request from the debugger.  Don't fire breakpoints
845872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while doing so.  (I don't think we currently do this at all, so
846872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this is mostly paranoia.)
847872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
8486995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  if (basket.thread == GetDebugThread()) {
8494dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Ignoring location event in JDWP thread";
8507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
851872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
852872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
853872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
854872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * The debugger variable display tab may invoke the interpreter to format
855872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * complex objects.  We want to ignore breakpoints and method entry/exit
856872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * traps while working on behalf of the debugger.
857872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   *
858872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If we don't ignore them, the VM will get hung up, because we'll
859872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * suspend on a breakpoint while the debugger is still waiting for its
860872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * method invocation to complete.
861872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
862761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
8634dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
8647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
865872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
866872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
868761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
8697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // We use the locked version because we have multiple possible match events.
8707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
8717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    match_list.reserve(event_list_size_);
8727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kBreakpoint) != 0) {
8737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
874761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
8757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kSingleStep) != 0) {
8767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
8777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodEntry) != 0) {
8797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
8807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodExit) != 0) {
8827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
8837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
8847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (match_list.empty()) {
8877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
8887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
8897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
891bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
8927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
8937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
8947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
8956995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
8967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
8977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
8987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
8997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
9007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
901872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
9027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
9037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
9047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
9057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
9077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
9087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
9097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
9107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
9117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
9127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
913872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
9147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
915872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
9167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
919761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  }
920872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
921138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
922138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
9236995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
924872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
925872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
926c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartiervoid JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field,
9276995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               mirror::Object* this_object, const JValue* fieldValue,
9286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               bool is_modification) {
9296995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
9306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(field != nullptr);
9316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(fieldValue != nullptr, is_modification);
9326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(field->IsStatic(), this_object == nullptr);
9336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
934261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ModBasket basket(Thread::Current());
9353f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.pLoc = pLoc;
936261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.locationClass.Assign(pLoc->method->GetDeclaringClass());
937261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.thisPtr.Assign(this_object);
938261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass.Get());
9396995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.field = field;
940bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
9413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (InvokeInProgress()) {
942261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz    VLOG(jdwp) << "Not posting field event during invoke (" << basket.className << ")";
9437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
9477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
9487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
9497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
9507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9523f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
9547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
9557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
9567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId instance_id = registry->Add(basket.thisPtr);
9577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
9587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FieldId field_id = Dbg::ToFieldId(field);
9597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
9607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
9617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
9637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
9647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
9657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
9667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
9677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetClassName(field_id);
968d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier    VLOG(jdwp) << StringPrintf("  field=%#" PRIx64, field_id) << " "
9697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetFieldName(field_id);
9707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
9717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9723f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
9747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
9757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
9766995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get field's reference type tag.
9787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
9796995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get instance type tag.
9817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  uint8_t tag;
9827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    ScopedObjectAccessUnchecked soa(Thread::Current());
984261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz    tag = Dbg::TagFromObject(soa, basket.thisPtr.Get());
9857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
9887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
9897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
9907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
9917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
9927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, type_tag);
9937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, field_type_id);
9947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddFieldId(pReq, field_id);
9957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
9967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, instance_id);
9977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (is_modification) {
9987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputFieldValue(field_id, fieldValue, pReq);
9996995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    }
10003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
10013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
10027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
10037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
10047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
10057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
10067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
10073f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  Dbg::ManageDeoptimization();
10083f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
10096995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
10103f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz}
10113f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
1012872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1013872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A thread is starting or stopping.
1014872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1015872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1016872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly
1017872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
10187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostThreadChange(Thread* thread, bool start) {
10196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  CHECK_EQ(thread, Thread::Current());
1020872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1021872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1022872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * I don't think this can happen.
1023872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1024761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
1025872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    LOG(WARNING) << "Not posting thread change during invoke";
10267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1027872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1028872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1029107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // We need the java.lang.Thread object associated to the starting/ending
1030107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // thread to get its JDWP id. Therefore we can't report event if there
1031107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // is no Java peer. This happens when the runtime shuts down and re-attaches
1032107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // the current thread without creating a Java peer.
1033107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  if (thread->GetPeer() == nullptr) {
1034107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz    return;
1035107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  }
1036107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz
1037261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ModBasket basket(thread);
1038872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
10407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
10417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
10427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
10437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
10447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1045bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
10467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
10477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
10486995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
10497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
10507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
10517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
10527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1053872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
10557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
10567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
1057234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
10587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
10597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
10607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
10617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd8BE(pReq, thread_id);
10627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1063872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
10657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
10667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1067234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  }
1068872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1069138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1070138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
10716995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1072872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1073872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1074872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1075872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send a polite "VM is dying" message to the debugger.
1076872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1077872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Skips the usual "event token" stuff.
1078872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1079376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMDeath() {
10804dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
1081872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1082872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = eventPrep();
1083872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, SP_NONE);
1084872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 1);
1085872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1086872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, EK_VM_DEATH);
1087872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 0);
1088761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  EventFinish(pReq);
1089872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
1090872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1091872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1092872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1093872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * An exception has been thrown.  It may or may not have been caught.
1094872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1095872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1096872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1097872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    ExceptionOnly, InstanceOnly
1098872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1099872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The "exceptionId" has not been added to the GC-visible object registry,
1100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * because there's a pretty good chance that we're not going to send it
1101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * up the debugger.
1102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
11037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
11046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                              const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
11056995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(exception_object != nullptr);
11066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pThrowLoc != nullptr);
11076995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pCatchLoc != nullptr);
1108a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1109a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1110a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  } else {
1111a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1112a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
1113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1114261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ModBasket basket(Thread::Current());
1115872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pThrowLoc;
1116a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1117261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz    basket.locationClass.Assign(pThrowLoc->method->GetDeclaringClass());
1118a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
1119261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass.Get());
1120261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.exceptionClass.Assign(exception_object->GetClass());
11216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.caught = (pCatchLoc->method != 0);
1122261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.thisPtr.Assign(thisPtr);
1123872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* don't try to post an exception caused by the debugger */
1125761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11264dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
11277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1128872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1129872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
11317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
11327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
11337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
11347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1135872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
11377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
11387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
11397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId exceptionId = registry->Add(exception_object);
11407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_throw_location;
11417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_catch_location;
11427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
11437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
11447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
11467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
11477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
11497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
11507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (jdwp_catch_location.class_id == 0) {
11517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=uncaught";
11527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    } else {
11537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
1154872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
11557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
11567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << exceptionClassName;
11577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
11587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1159872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
11617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
11627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
11637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
11657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
11667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
11677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
11687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_throw_location);
11697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, JT_OBJECT);
11707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, exceptionId);
11717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_catch_location);
11727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
11737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
11757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
11767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1178872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1179138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1180138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
11816995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1184872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Announce that a class has been loaded.
1186872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1187872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1188872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1189872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
11907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostClassPrepare(mirror::Class* klass) {
11916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(klass != nullptr);
1192872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1193261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  ModBasket basket(Thread::Current());
1194261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.locationClass.Assign(klass);
1195261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass.Get());
1196872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1197872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* suppress class prep caused by debugger */
1198761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11994dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
12007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1201872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1202872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
12047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
12057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
12067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
12077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1208872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
12107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
12117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
12127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId class_id = registry->AddRefType(basket.locationClass);
12137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // OLD-TODO - we currently always send both "verified" and "prepared" since
12157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // debuggers seem to like that.  There might be some advantage to honesty,
12167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // since the class may not yet be verified.
12177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
1218261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz  JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass.Get());
12197d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string temp;
12207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string signature(basket.locationClass->GetDescriptor(&temp));
12217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
12237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
12247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
12257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
12267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1227872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (thread_id == debug_thread_id_) {
12297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    /*
12307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * JDWP says that, for a class prep in the debugger thread, we
12317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * should set thread to null and if any threads were supposed
12327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * to be suspended then we suspend all other threads.
12337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     */
12347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
12357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    thread_id = 0;
12367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (suspend_policy == SP_EVENT_THREAD) {
12377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      suspend_policy = SP_ALL;
1238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
12397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12406995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
12417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
12427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
12437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
12447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
12467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
12477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
12487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
12497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
12507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, class_id);
12517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddUtf8String(pReq, signature);
12527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, status);
12537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
12567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
12577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1260138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1261138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
12626995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1264872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1266ad466adf38db74a9840659626858196091151a64Mathieu Chartier * Setup the header for a chunk of DDM data.
1267ad466adf38db74a9840659626858196091151a64Mathieu Chartier */
1268ad466adf38db74a9840659626858196091151a64Mathieu Chartiervoid JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size,
1269ad466adf38db74a9840659626858196091151a64Mathieu Chartier                                 uint8_t* out_header) {
1270ad466adf38db74a9840659626858196091151a64Mathieu Chartier  CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8));
1271ad466adf38db74a9840659626858196091151a64Mathieu Chartier  /* form the header (JDWP plus DDMS) */
1272ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header, header_size + data_len);
1273ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 4, NextRequestSerial());
1274ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 8, 0);     /* flags */
1275ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 9, kJDWPDdmCmdSet);
1276ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 10, kJDWPDdmCmd);
1277ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 11, type);
1278ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 15, data_len);
1279ad466adf38db74a9840659626858196091151a64Mathieu Chartier}
1280ad466adf38db74a9840659626858196091151a64Mathieu Chartier
1281ad466adf38db74a9840659626858196091151a64Mathieu Chartier/*
1282872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send up a chunk of DDM data.
1283872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * While this takes the form of a JDWP "event", it doesn't interact with
1285872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * other debugger traffic, and can't suspend the VM, so we skip all of
1286872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the fun event token gymnastics.
1287872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1288cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughesvoid JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1289ad466adf38db74a9840659626858196091151a64Mathieu Chartier  uint8_t header[kJDWPHeaderLen + 8] = { 0 };
1290872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  size_t dataLen = 0;
1291872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(iov != nullptr);
1293cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_GT(iov_count, 0);
1294cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_LT(iov_count, 10);
1295872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1296872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1298872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this by creating a new copy of the vector with space for the header.
1299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1300f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  std::vector<iovec> wrapiov;
1301f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  wrapiov.push_back(iovec());
1302cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  for (int i = 0; i < iov_count; i++) {
1303f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    wrapiov.push_back(iov[i]);
1304872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    dataLen += iov[i].iov_len;
1305872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1306872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1307ad466adf38db74a9840659626858196091151a64Mathieu Chartier  SetupChunkHeader(type, dataLen, sizeof(header), header);
1308872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1309872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_base = header;
1310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_len = sizeof(header);
1311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
131215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
131315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // than mutator for lock ordering reasons.
131400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
131562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
131662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (safe_to_release_mutator_lock_over_send) {
131738f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom    for (size_t i = 0; i < kMutatorLock; ++i) {
13187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
131962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        safe_to_release_mutator_lock_over_send = false;
132062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        break;
132162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      }
132215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    }
132315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
132415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  if (safe_to_release_mutator_lock_over_send) {
132515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Change state to waiting to allow GC, ... while we're sending.
132615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1327f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
132815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromSuspendedToRunnable();
132915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  } else {
133015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Send and possibly block GC...
1331f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
133215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
1333872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1334872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1335872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace JDWP
1336872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1337872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace art
1338