jdwp_event.cc revision c785344b87221f5e4e6473e5b762e4e61fe65dcf
1872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
2872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Copyright (C) 2008 The Android Open Source Project
3872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
4872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * you may not use this file except in compliance with the License.
6872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * You may obtain a copy of the License at
7872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
8872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
10872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Unless required by applicable law or agreed to in writing, software
11872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See the License for the specific language governing permissions and
14872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * limitations under the License.
15872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
17872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_event.h"
18872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <stddef.h>     /* for offsetof() */
20872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <stdlib.h>
21872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <string.h>
22872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <unistd.h>
23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
24c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h"
2507ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
26e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h"
2707ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "debugger.h"
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_constants.h"
2907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_expand_buf.h"
3007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h"
316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "jdwp/object_registry.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 */
122c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  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:
1363f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_ACCESS:
1373f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_MODIFICATION:
138138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return true;
139138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      default:
140138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return false;
141138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
142138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz}
143138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
144277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
14542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  switch (eventKind) {
14642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_BREAKPOINT:
14742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_SINGLE_STEP:
14842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kDexPcMoved;
14942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION:
15042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION_CATCH:
15142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kExceptionCaught;
15242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_ENTRY:
15342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodEntered;
15442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT:
15542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT_WITH_RETURN_VALUE:
15642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodExited;
15742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_ACCESS:
15842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldRead;
15942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_MODIFICATION:
16042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldWritten;
16142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    default:
16242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return 0;
16342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  }
16442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz}
16542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
166872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Add an event to the list.  Ordering is not important.
168872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
169872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If something prevents the event from being registered, e.g. it's a
170872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * single-step request on a thread that doesn't exist, the event will
171872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * not be added to the list, and an appropriate error will be returned.
172872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
173761928d24e4e7ed7776b52243eaf9095ad35f448Elliott HughesJdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
1747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent != nullptr);
1757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
1767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
17842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
17942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
18042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * If one or more "break"-type mods are used, register them with
18142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * the interpreter.
18242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
18342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
18442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
18542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      const JdwpEventMod* pMod = &pEvent->mods[i];
18642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
187033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Should only concern breakpoint, field access, field modification, step, and exception
188033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events.
189033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // However breakpoint requires specific handling. Field access, field modification and step
190033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // events need full deoptimization to be reported while exception event is reported during
191033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // exception handling.
192033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
193033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
194033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
19542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      } else if (pMod->modKind == MK_STEP) {
19642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
19742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
19942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
20042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        if (status != ERR_NONE) {
20142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz          return status;
20242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        }
2032435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes      }
204872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
20542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (NeedsFullDeoptimization(pEvent->eventKind)) {
2060ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2070ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2080ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullDeoptimization);
20942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    }
21042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
211872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
21242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
21342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
21442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2150ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kRegisterForEvent);
2160ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
21742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2184d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
219872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
220138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
221138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    /*
222138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     * Add to list.
223138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     */
224138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
2257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (event_list_ != nullptr) {
226138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      pEvent->next = event_list_;
227138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      event_list_->prev = pEvent;
228138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
229138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    event_list_ = pEvent;
230138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    ++event_list_size_;
231872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
232138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
233138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
234872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
235872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return ERR_NONE;
236872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
239872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove an event from the list.  This will also remove the event from
240872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any optimization tables, e.g. breakpoints.
241872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
242872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Does not free the JdwpEvent.
243872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the eventLock before calling here.
245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
246761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
2477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->prev == nullptr) {
248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* head of the list */
249f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK(event_list_ == pEvent);
250872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
251f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    event_list_ = pEvent->next;
252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->prev->next = pEvent->next;
254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
2567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent->next != nullptr) {
257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->next->prev = pEvent->prev;
2587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    pEvent->next = nullptr;
259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
2607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  pEvent->prev = nullptr;
261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
26242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
26342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
26442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * Unhook us from the interpreter, if necessary.
26542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
26642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
26742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
26842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      JdwpEventMod* pMod = &pEvent->mods[i];
26942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
270033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        // Like in RegisterEvent, we need specific handling for breakpoint only.
271033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        if (pEvent->eventKind == EK_BREAKPOINT) {
272033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz          Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
273033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz        }
27442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
27542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_STEP) {
27642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
27742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::UnconfigureStep(pMod->step.threadId);
27842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
279872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
280eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    if (NeedsFullDeoptimization(pEvent->eventKind)) {
2810ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2820ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2830ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
28542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
286872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
28742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
28942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2900ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
2910ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
29242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2934d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
295f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  --event_list_size_;
2967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(event_list_size_ != 0 || event_list_ == nullptr);
297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
298872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
300872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove the event with the given ID from the list.
301872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
302872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
303761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEventById(uint32_t requestId) {
304138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool found = false;
305138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
306138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
308138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
309138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      if (pEvent->requestId == requestId) {
310138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        found = true;
311138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        UnregisterEvent(pEvent);
312138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        EventFree(pEvent);
313138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        break;      /* there can be only one with a given ID */
314138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      }
315872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
316872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
317872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
318138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  if (found) {
319138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    Dbg::ManageDeoptimization();
320138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  } else {
321f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // Failure to find the event isn't really an error. For instance, it looks like Eclipse will
322f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // try to be extra careful and will explicitly remove one-off single-step events (using a
323f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // 'count' event modifier of 1). So the event may have already been removed as part of the
324f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    // event notification (see JdwpState::CleanupMatchList).
325f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz    VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId);
326138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  }
327872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
328872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
329872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
330872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove all entries from the event list.
331872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
332761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterAll() {
33350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), event_list_lock_);
334872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
335f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpEvent* pEvent = event_list_;
3367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  while (pEvent != nullptr) {
337872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    JdwpEvent* pNextEvent = pEvent->next;
338872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
339761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    UnregisterEvent(pEvent);
340872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    EventFree(pEvent);
341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent = pNextEvent;
342872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
343872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
3447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  event_list_ = nullptr;
345872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
346872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
347872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
348872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate a JdwpEvent struct with enough space to hold the specified
349872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * number of mod records.
350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
351872d4ec7225444d9400d30f9027247deb91012fdElliott HughesJdwpEvent* EventAlloc(int numMods) {
352872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEvent* newEvent;
353872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
354872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
355872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  memset(newEvent, 0, allocSize);
356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return newEvent;
357872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free a JdwpEvent.
361872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do not call this until the event has been removed from the list.
363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
364872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesvoid EventFree(JdwpEvent* pEvent) {
3657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (pEvent == nullptr) {
366872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
367872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* make sure it was removed from the list */
3707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->prev == nullptr);
3717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pEvent->next == nullptr);
372f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  /* want to check state->event_list_ != pEvent */
373872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
374872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
375872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Free any hairy bits in the mods.
376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
377872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = 0; i < pEvent->modCount; i++) {
378872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classMatch.classPattern);
3807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classMatch.classPattern = nullptr;
381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
382872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
383872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classExclude.classPattern);
3847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      pEvent->mods[i].classExclude.classPattern = nullptr;
385872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
386872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
388872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  free(pEvent);
389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
390872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
392872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Run through the list and remove any entries with an expired "count" mod
3937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * from the event list.
394872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
3957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) {
3967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
3977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    for (int i = 0; i < pEvent->modCount; ++i) {
398872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
399bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
400bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                   pEvent->requestId);
401761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        UnregisterEvent(pEvent);
402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        EventFree(pEvent);
403872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        break;
404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
405872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
406872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
407872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
408872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
409872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
410872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Match a string against a "restricted regular expression", which is just
411872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
412872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
413872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ("Restricted name globbing" might have been a better term.)
414872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
415761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic bool PatternMatch(const char* pattern, const std::string& target) {
416a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  size_t patLen = strlen(pattern);
417872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pattern[0] == '*') {
418872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    patLen--;
419a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    if (target.size() < patLen) {
420872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      return false;
421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
422a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else if (pattern[patLen-1] == '*') {
424a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strncmp(pattern, target.c_str(), patLen-1) == 0;
425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
426a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern, target.c_str()) == 0;
427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
428872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
429872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
431872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See if the event's mods match up with the contents of "basket".
432872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
433872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we find a Count mod before rejecting an event, we decrement it.  We
434872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * need to do this even if later mods cause us to ignore the event.
435872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
436bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
437b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEventMod* pMod = pEvent->mods;
439872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    switch (pMod->modKind) {
442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_COUNT:
443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK_GT(pMod->count.count, 0);
444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pMod->count.count--;
44543207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      if (pMod->count.count > 0) {
44643207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz        return false;
44743207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      }
448872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
449872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CONDITIONAL:
450872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK(false);  // should not be getting these
451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
452872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_THREAD_ONLY:
4536995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) {
454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
455872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
456872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
457872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_ONLY:
4586995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchType(basket.locationClass, pMod->classOnly.refTypeId)) {
459872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
460872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
461872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
462872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_MATCH:
463bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) {
464872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
465872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
466872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_EXCLUDE:
468bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (PatternMatch(pMod->classMatch.classPattern, basket.className)) {
469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
471872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
472872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_LOCATION_ONLY:
4736995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) {
474872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
475872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
476872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
477872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_EXCEPTION_ONLY:
4786995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (pMod->exceptionOnly.refTypeId != 0 &&
4796995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz          !Dbg::MatchType(basket.exceptionClass, pMod->exceptionOnly.refTypeId)) {
480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
481872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
4826995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if ((basket.caught && !pMod->exceptionOnly.caught) ||
4836995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz          (!basket.caught && !pMod->exceptionOnly.uncaught)) {
484872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
485872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
486872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_FIELD_ONLY:
4886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) {
489872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
491872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
492872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_STEP:
4936995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) {
494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_INSTANCE_ONLY:
4986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz      if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr)) {
499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
501872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
502872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    default:
5037b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
506872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
508872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
509872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
510872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments while holding the event list lock. This method
5137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * is used by FindMatchingEvents below.
514872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
5157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple times for grouped
5167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * events.
517872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
518872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * DO NOT call this multiple times for the same eventKind, as Count mods are
519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * decremented during the scan.
520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket,
5227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                         std::vector<JdwpEvent*>* match_list) {
523bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
5247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) {
5257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      match_list->push_back(pEvent);
526872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
527872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
528872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
529872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
530872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
5317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the
5327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments and return true if at least one event matches,
5337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * false otherwise.
5347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple
5367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * times for grouped events.
5377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz *
5387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * DO NOT call this multiple times for the same eventKind, as Count mods are
5397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * decremented during the scan.
5407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz */
5417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzbool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket,
5427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz                                   std::vector<JdwpEvent*>* match_list) {
5437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  MutexLock mu(Thread::Current(), event_list_lock_);
5447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  match_list->reserve(event_list_size_);
5457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FindMatchingEventsLocked(event_kind, basket, match_list);
5467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  return !match_list->empty();
5477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz}
5487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
5497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz/*
550872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Scan through the list of matches and determine the most severe
551872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspension policy.
552872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
5537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) {
554872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpSuspendPolicy policy = SP_NONE;
555872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
5567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (JdwpEvent* pEvent : match_list) {
5577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->suspend_policy > policy) {
5587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      policy = pEvent->suspend_policy;
559872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
560872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
561872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
562872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return policy;
563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
566872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Three possibilities:
567872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_NONE - do nothing
568872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_EVENT_THREAD - suspend ourselves
569872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_ALL - suspend everybody except JDWP support thread
570872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
57100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
572f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
573f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_NONE) {
574872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
575872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
576872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
577f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_ALL) {
578475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    Dbg::SuspendVM();
579872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
580f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
581872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
582872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
583872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is rare but possible -- see CLASS_PREPARE handling */
58400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (thread_self_id == debug_thread_id_) {
585761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
586872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
587872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
588872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
589872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  while (true) {
590872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::SuspendSelf();
591872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
592872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /*
593872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * The JDWP thread has told us (and possibly all other threads) to
594872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
595872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     */
5961558b577907b613864e98f05862543557263e864Sebastien Hertz    DebugInvokeReq* const pReq = Dbg::GetInvokeReq();
5971558b577907b613864e98f05862543557263e864Sebastien Hertz    if (pReq == nullptr) {
598761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      /*LOGD("SuspendByPolicy: no invoke needed");*/
599872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
600872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
601872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* grab this before posting/suspending again */
6032bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz    AcquireJdwpTokenForEvent(thread_self_id);
604872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
605872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::ExecuteMethod(pReq);
606872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
60900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
61000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              ObjectId threadId) {
6117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Thread* const self = Thread::Current();
61200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->AssertThreadSuspensionIsAllowable();
6137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(pReq != nullptr);
61400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  /* send request and possibly suspend ourselves */
6157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
6167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
6177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (suspend_policy != SP_NONE) {
6182bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz    AcquireJdwpTokenForEvent(threadId);
61900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
6207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  EventFinish(pReq);
621813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz  {
622813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING.
623813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    ScopedThreadStateChange stsc(self, kSuspended);
624813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz    SuspendByPolicy(suspend_policy, thread_self_id);
625813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz  }
6267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  self->TransitionFromSuspendedToRunnable();
62700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
62800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
629872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
630872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Determine if there is a method invocation in progress in the current
631872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread.
632872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
633475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
634872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * state.  If set, we're in the process of invoking a method.
635872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
636761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::InvokeInProgress() {
637872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
6381558b577907b613864e98f05862543557263e864Sebastien Hertz  return pReq != nullptr;
639872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
6412bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForCommand() {
6422bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
6432bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  SetWaitForJdwpToken(debug_thread_id_);
6442bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6452bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6462bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForCommand() {
6472bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread";
6482bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  ClearWaitForJdwpToken();
6492bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6502bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6512bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) {
6522bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
6532bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(debug_thread_id_, threadId) << "Not expected debug thread";
6542bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  SetWaitForJdwpToken(threadId);
6552bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6562bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6572bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForEvent() {
6582bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread";
6592bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  ClearWaitForJdwpToken();
6602bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz}
6612bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
662872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
663872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We need the JDWP thread to hold off on doing stuff while we post an
664872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event and then suspend ourselves.
665872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
666872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This could go to sleep waiting for another thread, so it's important
667872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that the thread be marked as VMWAIT before calling here.
668872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
6692bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::SetWaitForJdwpToken(ObjectId threadId) {
670872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  bool waited = false;
6712bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Thread* const self = Thread::Current();
6722bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(threadId, 0u);
6732bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(self->GetState(), kRunnable);
6742bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Locks::mutator_lock_->AssertNotHeld(self);
675872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is held for very brief periods; contention is unlikely */
6772bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  MutexLock mu(self, jdwp_token_lock_);
6782bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz
6792bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(jdwp_token_owner_thread_id_, threadId) << "Thread is already holding event thread lock";
680872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
681872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
682872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If another thread is already doing stuff, wait for it.  This can
683872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * go to sleep indefinitely.
684872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
6852bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  while (jdwp_token_owner_thread_id_ != 0) {
686d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
6872bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz                               jdwp_token_owner_thread_id_, threadId);
688872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    waited = true;
6892bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz    jdwp_token_cond_.Wait(self);
690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
691872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
6922bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  if (waited || threadId != debug_thread_id_) {
693d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
694872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
6952bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_owner_thread_id_ = threadId;
696872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
697872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
698872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
699872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Clear the threadId and signal anybody waiting.
700872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
7012bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ClearWaitForJdwpToken() {
702872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
703872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
7042bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz   * function is called by Dbg::SuspendSelf(), and the transition back
705872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * to RUNNING would confuse it.
706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
7072bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  Thread* const self = Thread::Current();
7082bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  MutexLock mu(self, jdwp_token_lock_);
709872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7102bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  CHECK_NE(jdwp_token_owner_thread_id_, 0U);
7112bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_);
712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7132bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_owner_thread_id_ = 0;
7142bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz  jdwp_token_cond_.Signal(self);
715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
716872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
717872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
718872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Prep an event.  Allocates storage for the message and leaves space for
719872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the header.
720872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
721872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstatic ExpandBuf* eventPrep() {
722872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = expandBufAlloc();
723872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAddSpace(pReq, kJDWPHeaderLen);
724872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return pReq;
725872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
726872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
727872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
728872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Write the header into the buffer and send the packet off to the debugger.
729872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
730872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Takes ownership of "pReq" (currently discards it).
731872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
732761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::EventFinish(ExpandBuf* pReq) {
733872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t* buf = expandBufGetBuffer(pReq);
734872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
735f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(buf, expandBufGetLength(pReq));
7367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set4BE(buf + 4, NextRequestSerial());
7377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 8, 0);     /* flags */
7387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 9, kJdwpEventCommandSet);
7397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  Set1(buf + 10, kJdwpCompositeCommand);
740872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
741761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  SendRequest(pReq);
742872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
743872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufFree(pReq);
744872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
745872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
746872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
747872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
748872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the debugger that we have finished initializing.  This is always
749872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * sent, even if the debugger hasn't requested it.
750872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
751872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This should be sent "before the main thread is started and before
752872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any application code has been executed".  The thread ID in the message
753872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * must be for the main thread.
754872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
7557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostVMStart() {
7567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE;
757872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId threadId = Dbg::GetThreadSelfId();
758872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "EVENT: " << EK_VM_START;
7607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
761872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
762761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  ExpandBuf* pReq = eventPrep();
7637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
7647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 1);
7657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, EK_VM_START);
7667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, 0);       /* requestId */
7677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAddObjectId(pReq, threadId);
768872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
769138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
770138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
771872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* send request and possibly suspend ourselves */
77200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
773872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
774872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list,
7766995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                       ObjectId thread_id)
777bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (size_t i = 0, e = match_list.size(); i < e; ++i) {
779bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    JdwpEvent* pEvent = match_list[i];
780bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
781bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz               << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
782bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
783bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  std::string thread_name;
7846995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  JdwpError error = Dbg::GetThreadName(thread_id, &thread_name);
785bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  if (error != JDWP::ERR_NONE) {
786bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    thread_name = "<unknown>";
787bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
7886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  VLOG(jdwp) << StringPrintf("  thread=%#" PRIx64, thread_id) << " " << thread_name;
7896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz}
7906995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
7916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzstatic void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location,
7926995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                             JDWP::JdwpLocation* jdwp_location)
7936995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
7946995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(event_location != nullptr);
7956995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(jdwp_location != nullptr);
7966995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc);
797bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz}
798bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
799872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
800872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A location of interest has been reached.  This handles:
801872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Breakpoint
802872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   SingleStep
803872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodEntry
804872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodExit
805872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * These four types must be grouped together in a single response.  The
806872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "eventFlags" indicates the type of event(s) that have happened.
807872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
808872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
809872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   LocationOnly (for breakpoint/step only)
811872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Step (for step only)
812872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
813872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Interesting test cases:
814872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
815872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
816872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
817872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Single-step to a line with a breakpoint.  Should get a single
818872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    event message with both events in it.
819872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
8207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr,
8216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                                  int eventFlags, const JValue* returnValue) {
8226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
8236995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc->method != nullptr);
8246995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr);
8256995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
827872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pLoc;
8286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = pLoc->method->GetDeclaringClass();
829872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
8306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
8316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
832872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
833872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
834872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * On rare occasions we may need to execute interpreted code in the VM
835872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while handling a request from the debugger.  Don't fire breakpoints
836872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while doing so.  (I don't think we currently do this at all, so
837872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this is mostly paranoia.)
838872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
8396995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  if (basket.thread == GetDebugThread()) {
8404dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Ignoring location event in JDWP thread";
8417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
842872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
845872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * The debugger variable display tab may invoke the interpreter to format
846872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * complex objects.  We want to ignore breakpoints and method entry/exit
847872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * traps while working on behalf of the debugger.
848872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   *
849872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If we don't ignore them, the VM will get hung up, because we'll
850872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * suspend on a breakpoint while the debugger is still waiting for its
851872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * method invocation to complete.
852872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
853761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
8544dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
8557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
856872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
857872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
859761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
8607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // We use the locked version because we have multiple possible match events.
8617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
8627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    match_list.reserve(event_list_size_);
8637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kBreakpoint) != 0) {
8647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list);
865761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
8667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kSingleStep) != 0) {
8677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list);
8687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodEntry) != 0) {
8707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list);
8717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if ((eventFlags & Dbg::kMethodExit) != 0) {
8737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list);
8747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list);
8757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    }
8767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (match_list.empty()) {
8787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
8797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
8807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
8817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
882bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
8837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
8847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
8857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
8866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
8877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
8887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
8897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
8907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
8917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
892872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
8947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
8957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
8967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
8977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
8987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
8997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
9007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
9017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
9027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
9037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq);
904872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
9057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
906872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
9077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
910761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  }
911872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
912138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
913138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
9146995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
915872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
916872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
917c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartiervoid JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field,
9186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               mirror::Object* this_object, const JValue* fieldValue,
9196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                               bool is_modification) {
9206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pLoc != nullptr);
9216995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(field != nullptr);
9226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(fieldValue != nullptr, is_modification);
9236995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK_EQ(field->IsStatic(), this_object == nullptr);
9246995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9253f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  ModBasket basket;
9263f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.pLoc = pLoc;
9276995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = pLoc->method->GetDeclaringClass();
9286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thisPtr = this_object;
9296995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
9306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
9316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.field = field;
932bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
9333f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (InvokeInProgress()) {
9343f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    VLOG(jdwp) << "Not posting field event during invoke";
9357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9363f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9373f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
9397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS;
9407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
9417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
9427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
9437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
9467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
9477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
9487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId instance_id = registry->Add(basket.thisPtr);
9497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass());
9507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  FieldId field_id = Dbg::ToFieldId(field);
9517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_location;
9527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pLoc, &jdwp_location);
9537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
9557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
9567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  location=" << jdwp_location;
9577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, instance_id);
9587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, field_type_id) << " "
9597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetClassName(field_id);
9607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, field_id) << " "
9617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << Dbg::GetFieldName(field_id);
9627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
9637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9643f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
9667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
9677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
9686995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get field's reference type tag.
9707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass());
9716995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
9727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // Get instance type tag.
9737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  uint8_t tag;
9747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    ScopedObjectAccessUnchecked soa(Thread::Current());
9767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    tag = Dbg::TagFromObject(soa, basket.thisPtr);
9777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9783f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
9807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
9817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
9827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
9837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_location);
9847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, type_tag);
9857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, field_type_id);
9867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddFieldId(pReq, field_id);
9877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
9887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, instance_id);
9897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (is_modification) {
9907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      Dbg::OutputFieldValue(field_id, fieldValue, pReq);
9916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    }
9923f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9933f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
9957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
9977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
9987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
9993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  Dbg::ManageDeoptimization();
10003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
10016995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
10023f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz}
10033f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
1004872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1005872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A thread is starting or stopping.
1006872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1007872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1008872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly
1009872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
10107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostThreadChange(Thread* thread, bool start) {
10116995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  CHECK_EQ(thread, Thread::Current());
1012872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1013872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1014872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * I don't think this can happen.
1015872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1016761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
1017872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    LOG(WARNING) << "Not posting thread change during invoke";
10187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1019872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1020872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1021107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // We need the java.lang.Thread object associated to the starting/ending
1022107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // thread to get its JDWP id. Therefore we can't report event if there
1023107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // is no Java peer. This happens when the runtime shuts down and re-attaches
1024107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  // the current thread without creating a Java peer.
1025107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  if (thread->GetPeer() == nullptr) {
1026107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz    return;
1027107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz  }
1028107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz
1029872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
10306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = thread;
1031872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
10337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH;
10347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(match_kind, basket, &match_list)) {
10357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
10367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
10377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1038bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
10397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
10407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
10416995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
10427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
10437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
10447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
10457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1046872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
10487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
10497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
1050234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
10517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
10527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
10537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
10547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd8BE(pReq, thread_id);
10557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1056872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
10587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
10597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1060234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  }
1061872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1062138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1063138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
10646995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1065872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1066872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1067872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1068872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send a polite "VM is dying" message to the debugger.
1069872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1070872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Skips the usual "event token" stuff.
1071872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1072376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMDeath() {
10734dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
1074872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1075872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = eventPrep();
1076872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, SP_NONE);
1077872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 1);
1078872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1079872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, EK_VM_DEATH);
1080872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 0);
1081761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  EventFinish(pReq);
1082872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
1083872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1084872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1085872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1086872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * An exception has been thrown.  It may or may not have been caught.
1087872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1088872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1089872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1090872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    ExceptionOnly, InstanceOnly
1091872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1092872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The "exceptionId" has not been added to the GC-visible object registry,
1093872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * because there's a pretty good chance that we're not going to send it
1094872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * up the debugger.
1095872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
10967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object,
10976995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                              const EventLocation* pCatchLoc, mirror::Object* thisPtr) {
10986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(exception_object != nullptr);
10996995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pThrowLoc != nullptr);
11006995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(pCatchLoc != nullptr);
1101a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1102a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr);
1103a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  } else {
1104a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    VLOG(jdwp) << "Unexpected: exception event with empty throw location";
1105a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
1106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11076995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  ModBasket basket;
1108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pThrowLoc;
1109a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  if (pThrowLoc->method != nullptr) {
1110a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    basket.locationClass = pThrowLoc->method->GetDeclaringClass();
1111a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  } else {
1112a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz    basket.locationClass = nullptr;
1113a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz  }
11146995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
11156995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
11166995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.exceptionClass = exception_object->GetClass();
11176995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.caught = (pCatchLoc->method != 0);
1118872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
1119872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1120872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* don't try to post an exception caused by the debugger */
1121761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11224dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
11237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1125872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
11277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) {
11287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
11297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
11307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1131872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
11337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
11347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
11357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId exceptionId = registry->Add(exception_object);
11367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_throw_location;
11377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpLocation jdwp_catch_location;
11387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location);
11397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location);
11407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
11427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass()));
11437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
11457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  throwLocation=" << jdwp_throw_location;
11467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (jdwp_catch_location.class_id == 0) {
11477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=uncaught";
11487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    } else {
11497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      VLOG(jdwp) << "  catchLocation=" << jdwp_catch_location;
1150872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
11517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  exception=%#" PRIx64, exceptionId) << " "
11527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz        << exceptionClassName;
11537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
11547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1155872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
11577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
11587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
11597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
11617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
11627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
11637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
11647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_throw_location);
11657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, JT_OBJECT);
11667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, exceptionId);
11677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddLocation(pReq, jdwp_catch_location);
11687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
11697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
11707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
11717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
11727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1173872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1174872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1175138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1176138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
11776995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1178872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1179872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1180872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1181872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Announce that a class has been loaded.
1182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1184872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
11867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostClassPrepare(mirror::Class* klass) {
11876995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  DCHECK(klass != nullptr);
1188872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  ModBasket basket;
11906995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.locationClass = klass;
11916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.thread = Thread::Current();
11926995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  basket.className = Dbg::GetClassName(basket.locationClass);
1193872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1194872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* suppress class prep caused by debugger */
1195761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11964dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
11977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
1198872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1199872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12007d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::vector<JdwpEvent*> match_list;
12017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) {
12027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    // No matching event.
12037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    return;
12047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1205872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list);
12077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectId thread_id = Dbg::GetThreadId(basket.thread);
12087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ObjectRegistry* registry = Dbg::GetObjectRegistry();
12097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  RefTypeId class_id = registry->AddRefType(basket.locationClass);
12107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // OLD-TODO - we currently always send both "verified" and "prepared" since
12127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // debuggers seem to like that.  There might be some advantage to honesty,
12137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  // since the class may not yet be verified.
12147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
12157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass);
12167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string temp;
12177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  std::string signature(basket.locationClass->GetDescriptor(&temp));
12187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12197d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (VLOG_IS_ON(jdwp)) {
12207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    LogMatchingEventsAndThread(match_list, thread_id);
12217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, class_id) << " " << signature;
12227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
12237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
1224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  if (thread_id == debug_thread_id_) {
12267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    /*
12277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * JDWP says that, for a class prep in the debugger thread, we
12287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * should set thread to null and if any threads were supposed
12297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     * to be suspended then we suspend all other threads.
12307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz     */
12317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
12327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    thread_id = 0;
12337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    if (suspend_policy == SP_EVENT_THREAD) {
12347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      suspend_policy = SP_ALL;
1235872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
12367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12376995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
12387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  ExpandBuf* pReq = eventPrep();
12397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd1(pReq, suspend_policy);
12407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  expandBufAdd4BE(pReq, match_list.size());
12417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  for (const JdwpEvent* pEvent : match_list) {
12437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, pEvent->eventKind);
12447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, pEvent->requestId);
12457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddObjectId(pReq, thread_id);
12467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd1(pReq, tag);
12477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddRefTypeId(pReq, class_id);
12487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAddUtf8String(pReq, signature);
12497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    expandBufAdd4BE(pReq, status);
12507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  }
12517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz
12527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  {
12537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
12547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz    CleanupMatchList(match_list);
1255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1257138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1258138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
12596995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
1260872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1262872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1263ad466adf38db74a9840659626858196091151a64Mathieu Chartier * Setup the header for a chunk of DDM data.
1264ad466adf38db74a9840659626858196091151a64Mathieu Chartier */
1265ad466adf38db74a9840659626858196091151a64Mathieu Chartiervoid JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size,
1266ad466adf38db74a9840659626858196091151a64Mathieu Chartier                                 uint8_t* out_header) {
1267ad466adf38db74a9840659626858196091151a64Mathieu Chartier  CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8));
1268ad466adf38db74a9840659626858196091151a64Mathieu Chartier  /* form the header (JDWP plus DDMS) */
1269ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header, header_size + data_len);
1270ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 4, NextRequestSerial());
1271ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 8, 0);     /* flags */
1272ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 9, kJDWPDdmCmdSet);
1273ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set1(out_header + 10, kJDWPDdmCmd);
1274ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 11, type);
1275ad466adf38db74a9840659626858196091151a64Mathieu Chartier  Set4BE(out_header + 15, data_len);
1276ad466adf38db74a9840659626858196091151a64Mathieu Chartier}
1277ad466adf38db74a9840659626858196091151a64Mathieu Chartier
1278ad466adf38db74a9840659626858196091151a64Mathieu Chartier/*
1279872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send up a chunk of DDM data.
1280872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1281872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * While this takes the form of a JDWP "event", it doesn't interact with
1282872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * other debugger traffic, and can't suspend the VM, so we skip all of
1283872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the fun event token gymnastics.
1284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1285cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughesvoid JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1286ad466adf38db74a9840659626858196091151a64Mathieu Chartier  uint8_t header[kJDWPHeaderLen + 8] = { 0 };
1287872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  size_t dataLen = 0;
1288872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz  CHECK(iov != nullptr);
1290cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_GT(iov_count, 0);
1291cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_LT(iov_count, 10);
1292872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1293872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1295872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this by creating a new copy of the vector with space for the header.
1296872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1297f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  std::vector<iovec> wrapiov;
1298f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  wrapiov.push_back(iovec());
1299cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  for (int i = 0; i < iov_count; i++) {
1300f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    wrapiov.push_back(iov[i]);
1301872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    dataLen += iov[i].iov_len;
1302872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1303872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1304ad466adf38db74a9840659626858196091151a64Mathieu Chartier  SetupChunkHeader(type, dataLen, sizeof(header), header);
1305872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1306872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_base = header;
1307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_len = sizeof(header);
1308872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
130915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
131015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // than mutator for lock ordering reasons.
131100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
131262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
131362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (safe_to_release_mutator_lock_over_send) {
131438f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom    for (size_t i = 0; i < kMutatorLock; ++i) {
13157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) {
131662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        safe_to_release_mutator_lock_over_send = false;
131762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        break;
131862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      }
131915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    }
132015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
132115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  if (safe_to_release_mutator_lock_over_send) {
132215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Change state to waiting to allow GC, ... while we're sending.
132315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1324f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
132515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromSuspendedToRunnable();
132615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  } else {
132715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Send and possibly block GC...
1328f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
132915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
1330872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1331872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1332872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace JDWP
1333872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1334872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace art
1335