jdwp_event.cc revision 7d95565c84d91ae5dcec4b89728ada208633de0c
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
2407ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
25e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h"
2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "debugger.h"
2707ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_constants.h"
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_expand_buf.h"
2907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h"
306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "jdwp/object_registry.h"
316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "mirror/art_field-inl.h"
326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "scoped_thread_state_change.h"
33693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread-inl.h"
3407ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
35872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
36872d4ec7225444d9400d30f9027247deb91012fdElliott HughesGeneral notes:
37872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
38872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe event add/remove stuff usually happens from the debugger thread,
39872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesin response to requests from the debugger, but can also happen as the
40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesresult of an event in an arbitrary thread (e.g. an event with a "count"
41872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmod expires).  It's important to keep the event list locked when processing
42872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesevents.
43872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
44872d4ec7225444d9400d30f9027247deb91012fdElliott HughesEvent posting can happen from any thread.  The JDWP thread will not usually
45872d4ec7225444d9400d30f9027247deb91012fdElliott Hughespost anything but VM start/death, but if a JDWP request causes a class
46872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesto be loaded, the ClassPrepare event will come from the JDWP thread.
47872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
48872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
49872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe can have serialization issues when we post an event to the debugger.
50872d4ec7225444d9400d30f9027247deb91012fdElliott HughesFor example, a thread could send an "I hit a breakpoint and am suspending
51872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmyself" message to the debugger.  Before it manages to suspend itself, the
52872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdebugger's response ("not interested, resume thread") arrives and is
53872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesprocessed.  We try to resume a thread that hasn't yet suspended.
54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
55872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThis means that, after posting an event to the debugger, we need to wait
56872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfor the event thread to suspend itself (and, potentially, all other threads)
57872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore processing any additional requests from the debugger.  While doing
58872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesso we need to be aware that multiple threads may be hitting breakpoints
59872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor other events simultaneously, so we either need to wait for all of them
60872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor serialize the events with each other.
61872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
62872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe current mechanism works like this:
63872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  Event thread:
64872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
65872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     for it if it's not currently available.
66872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - Post the event to the debugger.
67872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If appropriate, suspend others and then myself.  As part of suspending
68872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     myself, release the "I am posting" token.
69872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JDWP thread:
70872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - When an event arrives, see if somebody is posting an event.  If so,
71872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     sleep until we can acquire the "I am posting an event" token.  Release
72872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     it immediately and continue processing -- the event we have already
73872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     received should not interfere with other events that haven't yet
74872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     been posted.
75872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
76872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSome care must be taken to avoid deadlock:
77872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
78872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A and thread B exit near-simultaneously, and post thread-death
79872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   events with a "suspend all" clause
80872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A gets the event token, thread B sits and waits for it
81872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A wants to suspend all other threads, but thread B is waiting
82872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   for the token and can't be suspended
83872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
84872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSo we need to mark thread B in such a way that thread A doesn't wait for it.
85872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
86872d4ec7225444d9400d30f9027247deb91012fdElliott HughesIf we just bracket the "grab event token" call with a change to VMWAIT
87872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore sleeping, the switch back to RUNNING state when we get the token
88872d4ec7225444d9400d30f9027247deb91012fdElliott Hugheswill cause thread B to suspend (remember, thread A's global suspend is
89872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstill in force, even after it releases the token).  Suspending while
90872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesholding the event token is very bad, because it prevents the JDWP thread
91872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfrom processing incoming messages.
92872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
93872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe need to change to VMWAIT state at the *start* of posting an event,
94872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesand stay there until we either finish posting the event or decide to
95872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesput ourselves to sleep.  That way we don't interfere with anyone else and
96872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdon't allow anyone else to interfere with us.
97872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes*/
98872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
99872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#define kJdwpEventCommandSet    64
101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#define kJdwpCompositeCommand   100
102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
103872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art {
104872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
105872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace JDWP {
106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Stuff to compare against when deciding if a mod matches.  Only the
109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * values for mods valid for the event being evaluated will be filled in.
110872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The rest will be zeroed.
111872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
112872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct ModBasket {
1136995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  ModBasket() : pLoc(nullptr), thread(nullptr), locationClass(nullptr), exceptionClass(nullptr),
1146995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                caught(false), field(nullptr), thisPtr(nullptr) { }
1156995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
1166995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  const EventLocation*  pLoc;             /* LocationOnly */
1176995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  std::string           className;        /* ClassMatch/ClassExclude */
1186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  Thread*               thread;           /* ThreadOnly */
1196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  mirror::Class*        locationClass;    /* ClassOnly */
1206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  mirror::Class*        exceptionClass;   /* ExceptionOnly */
1216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  bool                  caught;           /* ExceptionOnly */
1226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  mirror::ArtField*     field;            /* FieldOnly */
1236995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  mirror::Object*       thisPtr;          /* InstanceOnly */
124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* nothing for StepOnly -- handled differently */
125872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes};
126872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
127138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertzstatic bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
128f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  if (!Dbg::RequiresDeoptimization()) {
129f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz    // We don't need deoptimization for debugging.
130f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz    return false;
131f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  }
132138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  switch (eventKind) {
133138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_ENTRY:
134138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT:
135138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT_WITH_RETURN_VALUE:
136138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_SINGLE_STEP:
1373f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_ACCESS:
1383f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_MODIFICATION:
139138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return true;
140138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      default:
141138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return false;
142138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
143138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz}
144138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
145277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
14642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  switch (eventKind) {
14742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_BREAKPOINT:
14842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_SINGLE_STEP:
14942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kDexPcMoved;
15042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION:
15142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION_CATCH:
15242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kExceptionCaught;
15342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_ENTRY:
15442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodEntered;
15542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT:
15642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT_WITH_RETURN_VALUE:
15742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodExited;
15842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_ACCESS:
15942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldRead;
16042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_MODIFICATION:
16142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldWritten;
16242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    default:
16342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return 0;
16442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  }
16542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz}
16642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
168872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Add an event to the list.  Ordering is not important.
169872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
170872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If something prevents the event from being registered, e.g. it's a
171872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * single-step request on a thread that doesn't exist, the event will
172872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * not be added to the list, and an appropriate error will be returned.
173872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
174761928d24e4e7ed7776b52243eaf9095ad35f448Elliott HughesJdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
1757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent != nullptr);
1767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
1777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
178872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
17942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
18042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
18142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * If one or more "break"-type mods are used, register them with
18242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * the interpreter.
18342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
18442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
18542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
18642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      const JdwpEventMod* pMod = &pEvent->mods[i];
18742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
188033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Should only concern breakpoint, field access, field modification, step, and exception
189033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events.
190033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // However breakpoint requires specific handling. Field access, field modification and step
191033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events need full deoptimization to be reported while exception event is reported during
192033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // exception handling.
193033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
194033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
195033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
19642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      } else if (pMod->modKind == MK_STEP) {
19742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
19942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
20042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
20142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        if (status != ERR_NONE) {
20242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz          return status;
20342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        }
2042435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes      }
205872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
20642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (NeedsFullDeoptimization(pEvent->eventKind)) {
2070ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2080ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2090ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullDeoptimization);
21042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    }
21142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
212872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
21342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
21442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
21542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2160ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kRegisterForEvent);
2170ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
21842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2194d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
220872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
221138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
222138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    /*
223138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     * Add to list.
224138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     */
225138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
2267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (event_list_ != nullptr) {
227138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      pEvent->next = event_list_;
228138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      event_list_->prev = pEvent;
229138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
230138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    event_list_ = pEvent;
231138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    ++event_list_size_;
232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
233138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
234138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
235872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
236872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return ERR_NONE;
237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
239872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
240872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove an event from the list.  This will also remove the event from
241872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any optimization tables, e.g. breakpoints.
242872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
243872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Does not free the JdwpEvent.
244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the eventLock before calling here.
246872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
247761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
2487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->prev == nullptr) {
249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* head of the list */
250f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK(event_list_ == pEvent);
251872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
252f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    event_list_ = pEvent->next;
253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->prev->next = pEvent->next;
255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
2577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->next != nullptr) {
258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->next->prev = pEvent->prev;
2597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    pEvent->next = nullptr;
260872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
2617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  pEvent->prev = nullptr;
262872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
26342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
26442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
26542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * Unhook us from the interpreter, if necessary.
26642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
26742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
26842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
26942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      JdwpEventMod* pMod = &pEvent->mods[i];
27042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
271033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Like in RegisterEvent, we need specific handling for breakpoint only.
272033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
273033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
274033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
27542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
27642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_STEP) {
27742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
27842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::UnconfigureStep(pMod->step.threadId);
27942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
280872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
28142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (pEvent->eventKind == EK_SINGLE_STEP) {
28242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // Special case for single-steps where we want to avoid the slow pattern deoptimize/undeoptimize
28342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // loop between each single-step. In a IDE, this would happens each time the user click on the
28442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // "single-step" button. Here we delay the full undeoptimization to the next resume
28542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // (VM.Resume or ThreadReference.Resume) or the end of the debugging session (VM.Dispose or
28642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // runtime shutdown).
28742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // Therefore, in a singles-stepping sequence, only the first single-step will trigger a full
28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // deoptimization and only the last single-step will trigger a full undeoptimization.
28942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      Dbg::DelayFullUndeoptimization();
29042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    } else if (NeedsFullDeoptimization(pEvent->eventKind)) {
2910ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2920ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2930ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
29542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
296872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
29742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
29842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
29942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
3000ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
3010ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
30242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
3034d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
304872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
305f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  --event_list_size_;
3067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(event_list_size_ != 0 || event_list_ == nullptr);
307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
308872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
309872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove the event with the given ID from the list.
311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
312872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
313761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEventById(uint32_t requestId) {
314138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool found = false;
315138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
316138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
317872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
318138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
319138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      if (pEvent->requestId == requestId) {
320138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        found = true;
321138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        UnregisterEvent(pEvent);
322138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        EventFree(pEvent);
323138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        break;      /* there can be only one with a given ID */
324138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      }
325872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
326872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
327872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
328138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  if (found) {
329138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    Dbg::ManageDeoptimization();
330138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  } else {
331f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
332f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // try to be extra careful and will explicitly remove one-off single-step events (using a
333f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // 'count' event modifier of 1). So the event may have already been removed as part of the
334f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // event notification (see JdwpState::CleanupMatchList).
335f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
336138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  }
337872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
338872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
339872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
340872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove all entries from the event list.
341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
342761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterAll() {
34350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), event_list_lock_);
344872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
345f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpEvent* pEvent = event_list_;
3467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  while (pEvent != nullptr) {
347872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    JdwpEvent* pNextEvent = pEvent->next;
348872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
349761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    UnregisterEvent(pEvent);
350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    EventFree(pEvent);
351872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent = pNextEvent;
352872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
353872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
3547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  event_list_ = nullptr;
355872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
357872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate a JdwpEvent struct with enough space to hold the specified
359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * number of mod records.
360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
361872d4ec7225444d9400d30f9027247deb91012fdElliott HughesJdwpEvent* EventAlloc(int numMods) {
362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEvent* newEvent;
363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
364872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
365872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  memset(newEvent, 0, allocSize);
366872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return newEvent;
367872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
370872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free a JdwpEvent.
371872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
372872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do not call this until the event has been removed from the list.
373872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
374872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesvoid EventFree(JdwpEvent* pEvent) {
3757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent == nullptr) {
376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
377872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
378872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* make sure it was removed from the list */
3807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
3817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
382f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  /* want to check state->event_list_ != pEvent */
383872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
384872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
385872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Free any hairy bits in the mods.
386872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = 0; i < pEvent->modCount; i++) {
388872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classMatch.classPattern);
3907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classMatch.classPattern = nullptr;
391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
392872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
393872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classExclude.classPattern);
3947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classExclude.classPattern = nullptr;
395872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
396872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
397872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
398872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  free(pEvent);
399872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
400872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
401872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Run through the list and remove any entries with an expired "count" mod
4037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * from the event list.
404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
4057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
4067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
4077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    for (int i = 0; i < pEvent->modCount; ++i) {
408872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
409bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
410bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                   pEvent->requestId);
411761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        UnregisterEvent(pEvent);
412872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        EventFree(pEvent);
413872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        break;
414872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
415872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
416872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
417872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
418872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
419872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
420872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Match a string against a "restricted regular expression", which is just
421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ("Restricted name globbing" might have been a better term.)
424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
425761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic bool PatternMatch(const char* pattern, const std::string& target) {
426a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  size_t patLen = strlen(pattern);
427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pattern[0] == '*') {
428872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    patLen--;
429a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    if (target.size() < patLen) {
430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      return false;
431872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
432a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
433872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else if (pattern[patLen-1] == '*') {
434a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strncmp(pattern, target.c_str(), patLen-1) == 0;
435872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
436a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern, target.c_str()) == 0;
437872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
439872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See if the event's mods match up with the contents of "basket".
442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we find a Count mod before rejecting an event, we decrement it.  We
444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * need to do this even if later mods cause us to ignore the event.
445872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
446bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
447b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
448872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEventMod* pMod = pEvent->mods;
449872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
450872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    switch (pMod->modKind) {
452872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_COUNT:
453872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK_GT(pMod->count.count, 0);
454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pMod->count.count--;
45543207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      if (pMod->count.count > 0) {
45643207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz        return false;
45743207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      }
458872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
459872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CONDITIONAL:
460872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK(false);  // should not be getting these
461872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
462872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_THREAD_ONLY:
4636995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
464872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
465872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
466872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_ONLY:
4686995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchType(basket.locationClass, pMod->classOnly.refTypeId)) {
469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
471872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
472872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_MATCH:
473bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
474872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
475872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
476872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
477872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_EXCLUDE:
478bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
479872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
481872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
482872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_LOCATION_ONLY:
4836995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
484872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
485872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
486872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_EXCEPTION_ONLY:
4886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (pMod->exceptionOnly.refTypeId != 0 &&
4896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz          !Dbg::MatchType(basket.exceptionClass, pMod->exceptionOnly.refTypeId)) {
490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
491872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
4926995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if ((basket.caught && !pMod->exceptionOnly.caught) ||
4936995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz          (!basket.caught && !pMod->exceptionOnly.uncaught)) {
494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_FIELD_ONLY:
4986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
501872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
502872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_STEP:
5036995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
506872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_INSTANCE_ONLY:
5086995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr)) {
509872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
510872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
511872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
512872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    default:
5137b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
514872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
515872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
516872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
517872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
518872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments while holding the event list lock. This method
5237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * is used by FindMatchingEvents below.
524872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
5257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple times for grouped
5267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * events.
527872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
528872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * DO NOT call this multiple times for the same eventKind, as Count mods are
529872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * decremented during the scan.
530872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
5327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                         std::vector<JdwpEvent*>* match_list) {
533bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
5347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
5357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      match_list->push_back(pEvent);
536872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
537872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
538872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
539872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
540872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments and return true if at least one event matches,
5437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * false otherwise.
5447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple
5467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * times for grouped events.
5477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * DO NOT call this multiple times for the same eventKind, as Count mods are
5497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * decremented during the scan.
5507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz */
5517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzbool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
5527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                   std::vector<JdwpEvent*>* match_list) {
5537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  MutexLock mu(Thread::Current(), event_list_lock_);
5547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  match_list->reserve(event_list_size_);
5557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FindMatchingEventsLocked(event_kind, basket, match_list);
5567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  return !match_list->empty();
5577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz}
5587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
5597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz/*
560872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Scan through the list of matches and determine the most severe
561872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspension policy.
562872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpSuspendPolicy policy = SP_NONE;
565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
5667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
5677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->suspend_policy > policy) {
5687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      policy = pEvent->suspend_policy;
569872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
570872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
571872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
572872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return policy;
573872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
574872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
575872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
576872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Three possibilities:
577872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_NONE - do nothing
578872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_EVENT_THREAD - suspend ourselves
579872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_ALL - suspend everybody except JDWP support thread
580872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
58100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
582f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
583f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_NONE) {
584872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
585872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
586872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
587f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_ALL) {
588475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    Dbg::SuspendVM();
589872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
590f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
591872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
592872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
593872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is rare but possible -- see CLASS_PREPARE handling */
59400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (thread_self_id == debug_thread_id_) {
595761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
596872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
597872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
598872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
599872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
600872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  while (true) {
601872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pReq->ready = true;
602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::SuspendSelf();
603872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pReq->ready = false;
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     */
609d38667a055d507492fd05f78519a7e1f0b85ea03Sebastien Hertz    if (!pReq->invoke_needed) {
610761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      /*LOGD("SuspendByPolicy: no invoke needed");*/
611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
612872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
613872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
614872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* grab this before posting/suspending again */
61500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    SetWaitForEventThread(thread_self_id);
616872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
617d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes    /* leave pReq->invoke_needed_ raised so we can check reentrancy */
618872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::ExecuteMethod(pReq);
619872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
620475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    pReq->error = ERR_NONE;
621872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
622872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
623872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
62400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
62500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              ObjectId threadId) {
6267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Thread* const self = Thread::Current();
62700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->AssertThreadSuspensionIsAllowable();
6287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pReq != nullptr);
62900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  /* send request and possibly suspend ourselves */
6307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
6317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
6327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (suspend_policy != SP_NONE) {
6337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    SetWaitForEventThread(threadId);
63400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
6357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  EventFinish(pReq);
6367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SuspendByPolicy(suspend_policy, thread_self_id);
6377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromSuspendedToRunnable();
63800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
63900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
641872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Determine if there is a method invocation in progress in the current
642872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread.
643872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
644475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
645872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * state.  If set, we're in the process of invoking a method.
646872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
647761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::InvokeInProgress() {
648872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
649d38667a055d507492fd05f78519a7e1f0b85ea03Sebastien Hertz  return pReq->invoke_needed;
650872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
651872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
652872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
653872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We need the JDWP thread to hold off on doing stuff while we post an
654872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event and then suspend ourselves.
655872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
656872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Call this with a threadId of zero if you just want to wait for the
657872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * current thread operation to complete.
658872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
659872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This could go to sleep waiting for another thread, so it's important
660872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that the thread be marked as VMWAIT before calling here.
661872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
662376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesvoid JdwpState::SetWaitForEventThread(ObjectId threadId) {
663872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  bool waited = false;
664872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
665872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is held for very brief periods; contention is unlikely */
66681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  Thread* self = Thread::Current();
66781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  MutexLock mu(self, event_thread_lock_);
668872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
669872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
670872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If another thread is already doing stuff, wait for it.  This can
671872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * go to sleep indefinitely.
672872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
673a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  while (event_thread_id_ != 0) {
674d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
675d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers                               event_thread_id_, threadId);
676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    waited = true;
677c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    event_thread_cond_.Wait(self);
678872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
679872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
680872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (waited || threadId != 0) {
681d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
682872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
683872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (threadId != 0) {
684a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes    event_thread_id_ = threadId;
685872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
686872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
687872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
688872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
689872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Clear the threadId and signal anybody waiting.
690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
691376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesvoid JdwpState::ClearWaitForEventThread() {
692872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
693872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
694872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * function is called by dvmSuspendSelf(), and the transition back
695872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * to RUNNING would confuse it.
696872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
697c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  Thread* self = Thread::Current();
698c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  MutexLock mu(self, event_thread_lock_);
699872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
700a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  CHECK_NE(event_thread_id_, 0U);
701d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", event_thread_id_);
702872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
703a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  event_thread_id_ = 0;
704872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
705c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  event_thread_cond_.Signal(self);
706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
708872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
709872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
710872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Prep an event.  Allocates storage for the message and leaves space for
711872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the header.
712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
713872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstatic ExpandBuf* eventPrep() {
714872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = expandBufAlloc();
715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAddSpace(pReq, kJDWPHeaderLen);
716872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return pReq;
717872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
718872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
719872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
720872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Write the header into the buffer and send the packet off to the debugger.
721872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
722872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Takes ownership of "pReq" (currently discards it).
723872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
724761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::EventFinish(ExpandBuf* pReq) {
725872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t* buf = expandBufGetBuffer(pReq);
726872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
727f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(buf, expandBufGetLength(pReq));
7287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set4BE(buf + 4, NextRequestSerial());
7297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 8, 0);     /* flags */
7307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 9, kJdwpEventCommandSet);
7317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 10, kJdwpCompositeCommand);
732872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
73399660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // Prevents from interleaving commands and events. Otherwise we could end up in sending an event
73499660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // before sending the reply of the command being processed and would lead to bad synchronization
73599660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // between the debugger and the debuggee.
73699660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  WaitForProcessingRequest();
73799660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz
738761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  SendRequest(pReq);
739872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
740872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufFree(pReq);
741872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
742872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
743872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
744872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
745872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the debugger that we have finished initializing.  This is always
746872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * sent, even if the debugger hasn't requested it.
747872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
748872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This should be sent "before the main thread is started and before
749872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any application code has been executed".  The thread ID in the message
750872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * must be for the main thread.
751872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
7527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostVMStart() {
7537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
754872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId threadId = Dbg::GetThreadSelfId();
755872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "EVENT: " << EK_VM_START;
7577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
758872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
759761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  ExpandBuf* pReq = eventPrep();
7607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
7617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 1);
7627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, EK_VM_START);
7637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 0);       /* requestId */
7647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAddObjectId(pReq, threadId);
765872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
766138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
767138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
768872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* send request and possibly suspend ourselves */
76900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
770872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
771872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list,
7736995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                       ObjectId thread_id)
774bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (size_t i = 0, e = match_list.size(); i < e; ++i) {
776bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    JdwpEvent* pEvent = match_list[i];
777bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
778bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz               << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
779bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
780bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  std::string thread_name;
7816995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  JdwpError error = Dbg::GetThreadName(thread_id, &thread_name);
782bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  if (error != JDWP::ERR_NONE) {
783bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    thread_name = "<unknown>";
784bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
7856995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  VLOG(jdwp) << StringPrintf("  thread=%#" PRIx64, thread_id) << " " << thread_name;
7866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz}
7876995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
7886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzstatic void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
7896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                             JDWP::JdwpLocation* jdwp_location)
7906995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(event_location != nullptr);
7926995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(jdwp_location != nullptr);
7936995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
794bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz}
795bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
796872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
797872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A location of interest has been reached.  This handles:
798872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Breakpoint
799872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   SingleStep
800872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodEntry
801872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodExit
802872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * These four types must be grouped together in a single response.  The
803872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "eventFlags" indicates the type of event(s) that have happened.
804872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
805872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
806872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
807872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   LocationOnly (for breakpoint/step only)
808872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Step (for step only)
809872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Interesting test cases:
811872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
812872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
813872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
814872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Single-step to a line with a breakpoint.  Should get a single
815872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    event message with both events in it.
816872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
8177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
8186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                  int eventFlags, const JValue* returnValue) {
8196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
8206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc->method != nullptr);
8216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
8226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
823872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
824872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pLoc;
8256995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = pLoc->method->GetDeclaringClass();
826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
8276995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
8286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
829872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
830872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
831872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * On rare occasions we may need to execute interpreted code in the VM
832872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while handling a request from the debugger.  Don't fire breakpoints
833872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while doing so.  (I don't think we currently do this at all, so
834872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this is mostly paranoia.)
835872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
8366995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  if (basket.thread == GetDebugThread()) {
8374dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Ignoring location event in JDWP thread";
8387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
839872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
840872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
841872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
842872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * The debugger variable display tab may invoke the interpreter to format
843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * complex objects.  We want to ignore breakpoints and method entry/exit
844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * traps while working on behalf of the debugger.
845872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   *
846872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If we don't ignore them, the VM will get hung up, because we'll
847872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * suspend on a breakpoint while the debugger is still waiting for its
848872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * method invocation to complete.
849872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
850761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
8514dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
8527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
853872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
854872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
856761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
8577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // We use the locked version because we have multiple possible match events.
8587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
8597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    match_list.reserve(event_list_size_);
8607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kBreakpoint) != 0) {
8617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
862761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
8637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kSingleStep) != 0) {
8647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
8657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodEntry) != 0) {
8677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
8687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodExit) != 0) {
8707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
8717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
8727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (match_list.empty()) {
8757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
8767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
8777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
879bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
8807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
8817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
8827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
8836995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
8847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
8857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
8867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
8877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
8887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
889872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
8917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
8927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
8937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
8947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
8957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
8967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
8977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
8987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
8997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
9007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
901872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
9027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
903872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
9047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
907761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  }
908872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
909138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
910138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
9116995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
912872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
913872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
9147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field,
9156995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               mirror::Object* this_object, const JValue* fieldValue,
9166995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               bool is_modification) {
9176995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
9186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(field != nullptr);
9196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(fieldValue != nullptr, is_modification);
9206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(field->IsStatic(), this_object == nullptr);
9216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9223f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  ModBasket basket;
9233f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.pLoc = pLoc;
9246995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = pLoc->method->GetDeclaringClass();
9256995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thisPtr = this_object;
9266995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
9276995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
9286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.field = field;
929bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
9303f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (InvokeInProgress()) {
9313f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    VLOG(jdwp) << "Not posting field event during invoke";
9327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9333f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9343f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
9367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
9377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
9387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
9397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
9437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
9447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
9457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId instance_id = registry->Add(basket.thisPtr);
9467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
9477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FieldId field_id = Dbg::ToFieldId(field);
9487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
9497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
9507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
9527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
9537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
9547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
9557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
9567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetClassName(field_id);
9577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, field_id) << " "
9587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetFieldName(field_id);
9597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
9607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9613f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
9637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
9647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
9656995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get field's reference type tag.
9677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
9686995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get instance type tag.
9707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  uint8_t tag;
9717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    ScopedObjectAccessUnchecked soa(Thread::Current());
9737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    tag = Dbg::TagFromObject(soa, basket.thisPtr);
9747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9753f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
9777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
9787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
9797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
9807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
9817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, type_tag);
9827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, field_type_id);
9837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddFieldId(pReq, field_id);
9847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
9857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, instance_id);
9867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (is_modification) {
9877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputFieldValue(field_id, fieldValue, pReq);
9886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    }
9893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
9947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9963f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  Dbg::ManageDeoptimization();
9973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
9993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz}
10003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
1001872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1002872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A thread is starting or stopping.
1003872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1004872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1005872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly
1006872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
10077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostThreadChange(Thread* thread, bool start) {
10086995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  CHECK_EQ(thread, Thread::Current());
1009872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1010872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1011872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * I don't think this can happen.
1012872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1013761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
1014872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    LOG(WARNING) << "Not posting thread change during invoke";
10157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1016872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1017872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1018872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
10196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = thread;
1020872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
10227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
10237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
10247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
10257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
10267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1027bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
10287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
10297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
10306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
10317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
10327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
10337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
10347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1035872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
10377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
10387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
1039234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
10407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
10417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
10427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
10437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd8BE(pReq, thread_id);
10447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1045872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
10477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
10487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1049234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  }
1050872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1051138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1052138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
10536995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1054872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1055872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1056872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1057872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send a polite "VM is dying" message to the debugger.
1058872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1059872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Skips the usual "event token" stuff.
1060872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1061376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMDeath() {
10624dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
1063872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1064872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = eventPrep();
1065872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, SP_NONE);
1066872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 1);
1067872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1068872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, EK_VM_DEATH);
1069872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 0);
1070761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  EventFinish(pReq);
1071872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
1072872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1073872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1074872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1075872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * An exception has been thrown.  It may or may not have been caught.
1076872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1077872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1078872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1079872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    ExceptionOnly, InstanceOnly
1080872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1081872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The "exceptionId" has not been added to the GC-visible object registry,
1082872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * because there's a pretty good chance that we're not going to send it
1083872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * up the debugger.
1084872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
10857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
10866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                              const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
10876995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(exception_object != nullptr);
10886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pThrowLoc != nullptr);
10896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pCatchLoc != nullptr);
1090a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1091a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1092a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  } else {
1093a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1094a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
1095872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10966995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  ModBasket basket;
1097872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pThrowLoc;
1098a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1099a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    basket.locationClass = pThrowLoc->method->GetDeclaringClass();
1100a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  } else {
1101a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    basket.locationClass = nullptr;
1102a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
11036995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
11046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
11056995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.exceptionClass = exception_object->GetClass();
11066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.caught = (pCatchLoc->method != 0);
1107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
1108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* don't try to post an exception caused by the debugger */
1110761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11114dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
11127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1114872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
11167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
11177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
11187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
11197d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1120872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
11227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
11237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
11247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId exceptionId = registry->Add(exception_object);
11257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_throw_location;
11267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_catch_location;
11277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
11287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
11297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
11317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
11327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
11347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
11357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (jdwp_catch_location.class_id == 0) {
11367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=uncaught";
11377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    } else {
11387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
1139872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
11407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
11417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << exceptionClassName;
11427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
11437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1144872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
11467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
11477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
11487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
11507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
11517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
11527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
11537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_throw_location);
11547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, JT_OBJECT);
11557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, exceptionId);
11567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_catch_location);
11577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
11587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
11607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
11617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1162872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1163872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1164138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1165138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
11666995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1168872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1169872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1170872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Announce that a class has been loaded.
1171872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1172872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1173872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1174872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
11757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostClassPrepare(mirror::Class* klass) {
11766995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(klass != nullptr);
1177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11786995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  ModBasket basket;
11796995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = klass;
11806995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
11816995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
1182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* suppress class prep caused by debugger */
1184761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11854dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
11867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1187872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1188872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
11907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
11917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
11927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
11937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1194872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
11967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
11977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
11987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId class_id = registry->AddRefType(basket.locationClass);
11997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // OLD-TODO - we currently always send both "verified" and "prepared" since
12017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // debuggers seem to like that.  There might be some advantage to honesty,
12027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // since the class may not yet be verified.
12037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
12047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass);
12057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string temp;
12067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string signature(basket.locationClass->GetDescriptor(&temp));
12077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
12097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
12107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
12117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
12127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1213872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (thread_id == debug_thread_id_) {
12157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    /*
12167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * JDWP says that, for a class prep in the debugger thread, we
12177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * should set thread to null and if any threads were supposed
12187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * to be suspended then we suspend all other threads.
12197d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     */
12207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
12217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    thread_id = 0;
12227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (suspend_policy == SP_EVENT_THREAD) {
12237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      suspend_policy = SP_ALL;
1224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
12257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12266995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
12277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
12287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
12297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
12307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
12327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
12337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
12347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
12357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
12367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, class_id);
12377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddUtf8String(pReq, signature);
12387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, status);
12397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
12427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
12437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1246138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1247138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
12486995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1250872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1251872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send up a chunk of DDM data.
1253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * While this takes the form of a JDWP "event", it doesn't interact with
1255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * other debugger traffic, and can't suspend the VM, so we skip all of
1256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the fun event token gymnastics.
1257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1258cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughesvoid JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t header[kJDWPHeaderLen + 8];
1260872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  size_t dataLen = 0;
1261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(iov != nullptr);
1263cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_GT(iov_count, 0);
1264cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_LT(iov_count, 10);
1265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1266872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1267872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1268872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this by creating a new copy of the vector with space for the header.
1269872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1270f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  std::vector<iovec> wrapiov;
1271f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  wrapiov.push_back(iovec());
1272cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  for (int i = 0; i < iov_count; i++) {
1273f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    wrapiov.push_back(iov[i]);
1274872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    dataLen += iov[i].iov_len;
1275872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1276872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1277872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* form the header (JDWP plus DDMS) */
1278f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(header, sizeof(header) + dataLen);
12797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set4BE(header + 4, NextRequestSerial());
12807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(header + 8, 0);     /* flags */
12817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(header + 9, kJDWPDdmCmdSet);
12827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(header + 10, kJDWPDdmCmd);
12837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set4BE(header + 11, type);
12847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set4BE(header + 15, dataLen);
1285872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1286872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_base = header;
1287872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_len = sizeof(header);
1288872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
128915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
129015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // than mutator for lock ordering reasons.
129100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
129262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
129362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (safe_to_release_mutator_lock_over_send) {
129438f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom    for (size_t i = 0; i < kMutatorLock; ++i) {
12957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
129662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        safe_to_release_mutator_lock_over_send = false;
129762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        break;
129862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      }
129915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    }
130015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
130115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  if (safe_to_release_mutator_lock_over_send) {
130215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Change state to waiting to allow GC, ... while we're sending.
130315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1304f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
130515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromSuspendedToRunnable();
130615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  } else {
130715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Send and possibly block GC...
1308f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
130915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
1310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1312872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace JDWP
1313872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1314872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace art
1315