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