jdwp_event.cc revision 0ec17d2ddb69d3f5c46ccad62e82c0ffd6219428
1872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
2872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Copyright (C) 2008 The Android Open Source Project
3872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
4872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * you may not use this file except in compliance with the License.
6872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * You may obtain a copy of the License at
7872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
8872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
10872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Unless required by applicable law or agreed to in writing, software
11872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See the License for the specific language governing permissions and
14872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * limitations under the License.
15872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
17872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_event.h"
18872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <stddef.h>     /* for offsetof() */
20872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <stdlib.h>
21872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <string.h>
22872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <unistd.h>
23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
2407ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
25e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h"
2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "debugger.h"
2707ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_constants.h"
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_expand_buf.h"
2907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h"
30693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread-inl.h"
3107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
32872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
33872d4ec7225444d9400d30f9027247deb91012fdElliott HughesGeneral notes:
34872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
35872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe event add/remove stuff usually happens from the debugger thread,
36872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesin response to requests from the debugger, but can also happen as the
37872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesresult of an event in an arbitrary thread (e.g. an event with a "count"
38872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmod expires).  It's important to keep the event list locked when processing
39872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesevents.
40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
41872d4ec7225444d9400d30f9027247deb91012fdElliott HughesEvent posting can happen from any thread.  The JDWP thread will not usually
42872d4ec7225444d9400d30f9027247deb91012fdElliott Hughespost anything but VM start/death, but if a JDWP request causes a class
43872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesto be loaded, the ClassPrepare event will come from the JDWP thread.
44872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
45872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
46872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe can have serialization issues when we post an event to the debugger.
47872d4ec7225444d9400d30f9027247deb91012fdElliott HughesFor example, a thread could send an "I hit a breakpoint and am suspending
48872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmyself" message to the debugger.  Before it manages to suspend itself, the
49872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdebugger's response ("not interested, resume thread") arrives and is
50872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesprocessed.  We try to resume a thread that hasn't yet suspended.
51872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
52872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThis means that, after posting an event to the debugger, we need to wait
53872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfor the event thread to suspend itself (and, potentially, all other threads)
54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore processing any additional requests from the debugger.  While doing
55872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesso we need to be aware that multiple threads may be hitting breakpoints
56872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor other events simultaneously, so we either need to wait for all of them
57872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor serialize the events with each other.
58872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
59872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe current mechanism works like this:
60872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  Event thread:
61872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
62872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     for it if it's not currently available.
63872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - Post the event to the debugger.
64872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - If appropriate, suspend others and then myself.  As part of suspending
65872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     myself, release the "I am posting" token.
66872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JDWP thread:
67872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   - When an event arrives, see if somebody is posting an event.  If so,
68872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     sleep until we can acquire the "I am posting an event" token.  Release
69872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     it immediately and continue processing -- the event we have already
70872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     received should not interfere with other events that haven't yet
71872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     been posted.
72872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
73872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSome care must be taken to avoid deadlock:
74872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
75872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A and thread B exit near-simultaneously, and post thread-death
76872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   events with a "suspend all" clause
77872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A gets the event token, thread B sits and waits for it
78872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A wants to suspend all other threads, but thread B is waiting
79872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   for the token and can't be suspended
80872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
81872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSo we need to mark thread B in such a way that thread A doesn't wait for it.
82872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
83872d4ec7225444d9400d30f9027247deb91012fdElliott HughesIf we just bracket the "grab event token" call with a change to VMWAIT
84872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore sleeping, the switch back to RUNNING state when we get the token
85872d4ec7225444d9400d30f9027247deb91012fdElliott Hugheswill cause thread B to suspend (remember, thread A's global suspend is
86872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstill in force, even after it releases the token).  Suspending while
87872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesholding the event token is very bad, because it prevents the JDWP thread
88872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfrom processing incoming messages.
89872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
90872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe need to change to VMWAIT state at the *start* of posting an event,
91872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesand stay there until we either finish posting the event or decide to
92872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesput ourselves to sleep.  That way we don't interfere with anyone else and
93872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdon't allow anyone else to interfere with us.
94872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes*/
95872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
96872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
97872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#define kJdwpEventCommandSet    64
98872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#define kJdwpCompositeCommand   100
99872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art {
101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace JDWP {
103872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
104872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
105872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Stuff to compare against when deciding if a mod matches.  Only the
106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * values for mods valid for the event being evaluated will be filled in.
107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The rest will be zeroed.
108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct ModBasket {
110162fd33474038f0de0388338ca007ecf400bb3dfjeffhao  ModBasket() : pLoc(NULL), threadId(0), classId(0), excepClassId(0),
111479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz                caught(false), fieldTypeID(0), fieldId(0), thisPtr(0) { }
112162fd33474038f0de0388338ca007ecf400bb3dfjeffhao
113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  const JdwpLocation* pLoc;           /* LocationOnly */
114a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  std::string         className;      /* ClassMatch/ClassExclude */
115872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId            threadId;       /* ThreadOnly */
116872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  RefTypeId           classId;        /* ClassOnly */
117872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  RefTypeId           excepClassId;   /* ExceptionOnly */
118872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  bool                caught;         /* ExceptionOnly */
119479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz  RefTypeId           fieldTypeID;    /* FieldOnly */
120479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz  FieldId             fieldId;        /* FieldOnly */
121872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId            thisPtr;        /* InstanceOnly */
122872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* nothing for StepOnly -- handled differently */
123872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes};
124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
125138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertzstatic bool NeedsFullDeoptimization(JdwpEventKind eventKind) {
126138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  switch (eventKind) {
127138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_ENTRY:
128138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT:
129138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_METHOD_EXIT_WITH_RETURN_VALUE:
130138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      case EK_SINGLE_STEP:
1313f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_ACCESS:
1323f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      case EK_FIELD_MODIFICATION:
133138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return true;
134138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      default:
135138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        return false;
136138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
137138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz}
138138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
13942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertzuint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) {
14042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  switch (eventKind) {
14142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_BREAKPOINT:
14242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_SINGLE_STEP:
14342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kDexPcMoved;
14442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION:
14542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_EXCEPTION_CATCH:
14642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kExceptionCaught;
14742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_ENTRY:
14842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodEntered;
14942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT:
15042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_METHOD_EXIT_WITH_RETURN_VALUE:
15142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kMethodExited;
15242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_ACCESS:
15342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldRead;
15442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    case EK_FIELD_MODIFICATION:
15542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return instrumentation::Instrumentation::kFieldWritten;
15642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    default:
15742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      return 0;
15842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  }
15942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz}
16042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
161872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
162872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Add an event to the list.  Ordering is not important.
163872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
164872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If something prevents the event from being registered, e.g. it's a
165872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * single-step request on a thread that doesn't exist, the event will
166872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * not be added to the list, and an appropriate error will be returned.
167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
168761928d24e4e7ed7776b52243eaf9095ad35f448Elliott HughesJdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) {
169872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(pEvent != NULL);
170872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(pEvent->prev == NULL);
171872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(pEvent->next == NULL);
172872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
17342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
17442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
17542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * If one or more "break"-type mods are used, register them with
17642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * the interpreter.
17742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
17842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
17942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
18042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      const JdwpEventMod* pMod = &pEvent->mods[i];
18142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
18242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for Breakpoint, Step, and Exception */
18342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::WatchLocation(&pMod->locationOnly.loc, &req);
18442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      } else if (pMod->modKind == MK_STEP) {
18542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
18642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
18742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
18842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth);
18942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        if (status != ERR_NONE) {
19042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz          return status;
19142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        }
1922435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes      }
193872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
19442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (NeedsFullDeoptimization(pEvent->eventKind)) {
1950ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
1960ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
1970ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullDeoptimization);
19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    }
19942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
200872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
20142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
20242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
20342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2040ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kRegisterForEvent);
2050ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
20642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2074d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
208872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
209138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
210138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    /*
211138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     * Add to list.
212138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz     */
213138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
214138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    if (event_list_ != NULL) {
215138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      pEvent->next = event_list_;
216138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      event_list_->prev = pEvent;
217138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    }
218138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    event_list_ = pEvent;
219138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    ++event_list_size_;
220872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
221138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
222138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
223872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return ERR_NONE;
225872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
226872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
227872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
228872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove an event from the list.  This will also remove the event from
229872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any optimization tables, e.g. breakpoints.
230872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
231872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Does not free the JdwpEvent.
232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
233872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the eventLock before calling here.
234872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
235761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEvent(JdwpEvent* pEvent) {
236872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pEvent->prev == NULL) {
237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* head of the list */
238f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK(event_list_ == pEvent);
239872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
240f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    event_list_ = pEvent->next;
241872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
242872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->prev->next = pEvent->next;
243872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pEvent->next != NULL) {
246872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->next->prev = pEvent->prev;
247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent->next = NULL;
248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  pEvent->prev = NULL;
250872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
25142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  {
25242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    /*
25342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     * Unhook us from the interpreter, if necessary.
25442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz     */
25542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
25642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    for (int i = 0; i < pEvent->modCount; i++) {
25742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      JdwpEventMod* pMod = &pEvent->mods[i];
25842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_LOCATION_ONLY) {
25942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for Breakpoint, Step, and Exception */
26042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req);
26142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
26242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      if (pMod->modKind == MK_STEP) {
26342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        /* should only be for EK_SINGLE_STEP; should only be one */
26442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        Dbg::UnconfigureStep(pMod->step.threadId);
26542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      }
266872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
26742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    if (pEvent->eventKind == EK_SINGLE_STEP) {
26842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // Special case for single-steps where we want to avoid the slow pattern deoptimize/undeoptimize
26942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // loop between each single-step. In a IDE, this would happens each time the user click on the
27042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // "single-step" button. Here we delay the full undeoptimization to the next resume
27142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // (VM.Resume or ThreadReference.Resume) or the end of the debugging session (VM.Dispose or
27242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // runtime shutdown).
27342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // Therefore, in a singles-stepping sequence, only the first single-step will trigger a full
27442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      // deoptimization and only the last single-step will trigger a full undeoptimization.
27542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz      Dbg::DelayFullUndeoptimization();
27642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    } else if (NeedsFullDeoptimization(pEvent->eventKind)) {
2770ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing);
2780ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      CHECK(req.Method() == nullptr);
2790ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      req.SetKind(DeoptimizationRequest::kFullUndeoptimization);
280872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
28142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
282872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
28342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind);
28442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  if (instrumentation_event != 0) {
28542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    DeoptimizationRequest req;
2860ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetKind(DeoptimizationRequest::kUnregisterForEvent);
2870ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    req.SetInstrumentationEvent(instrumentation_event);
28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    Dbg::RequestDeoptimization(req);
2894d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  }
290872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
291f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  --event_list_size_;
292f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  CHECK(event_list_size_ != 0 || event_list_ == NULL);
293872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
295872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
296872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove the event with the given ID from the list.
297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
298872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Failure to find the event isn't really an error, but it is a little
299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * weird.  (It looks like Eclipse will try to be extra careful and will
300872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * explicitly remove one-off single-step events.)
301872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
302761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEventById(uint32_t requestId) {
303138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool found = false;
304138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  {
305138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
306872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
307138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
308138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      if (pEvent->requestId == requestId) {
309138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        found = true;
310138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        UnregisterEvent(pEvent);
311138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        EventFree(pEvent);
312138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz        break;      /* there can be only one with a given ID */
313138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz      }
314872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
315872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
316872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
317138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  if (found) {
318138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    Dbg::ManageDeoptimization();
319138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  } else {
3204d466a8e4587422c989705dce3b2a19e7f0137f5Brian Carlstrom    LOG(WARNING) << StringPrintf("Odd: no match when removing event reqId=0x%04x", requestId);
321138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  }
322872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
323872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
324872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
325872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove all entries from the event list.
326872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
327761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterAll() {
32850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  MutexLock mu(Thread::Current(), event_list_lock_);
329872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
330f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpEvent* pEvent = event_list_;
331872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  while (pEvent != NULL) {
332872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    JdwpEvent* pNextEvent = pEvent->next;
333872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
334761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    UnregisterEvent(pEvent);
335872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    EventFree(pEvent);
336872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pEvent = pNextEvent;
337872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
338872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
339f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  event_list_ = NULL;
340872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
342872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
343872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate a JdwpEvent struct with enough space to hold the specified
344872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * number of mod records.
345872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
346872d4ec7225444d9400d30f9027247deb91012fdElliott HughesJdwpEvent* EventAlloc(int numMods) {
347872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEvent* newEvent;
348872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
349872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  memset(newEvent, 0, allocSize);
351872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return newEvent;
352872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
353872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
354872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
355872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free a JdwpEvent.
356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
357872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do not call this until the event has been removed from the list.
358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesvoid EventFree(JdwpEvent* pEvent) {
360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pEvent == NULL) {
361872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
364872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* make sure it was removed from the list */
365872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(pEvent->prev == NULL);
366872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(pEvent->next == NULL);
367f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  /* want to check state->event_list_ != pEvent */
368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
370872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Free any hairy bits in the mods.
371872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
372872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = 0; i < pEvent->modCount; i++) {
373872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
374872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classMatch.classPattern);
375872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pEvent->mods[i].classMatch.classPattern = NULL;
376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
377872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
378872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      free(pEvent->mods[i].classExclude.classPattern);
379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pEvent->mods[i].classExclude.classPattern = NULL;
380872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
382872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
383872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  free(pEvent);
384872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
385872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
386872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate storage for matching events.  To keep things simple we
388872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * use an array with enough storage for the entire list.
389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
390872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The state->eventLock should be held before calling.
391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
392761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic JdwpEvent** AllocMatchList(size_t event_count) {
393761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  return new JdwpEvent*[event_count];
394872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
395872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
396872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
397872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Run through the list and remove any entries with an expired "count" mod
398872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * from the event list, then free the match list.
399872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
400bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzvoid JdwpState::CleanupMatchList(JdwpEvent** match_list, size_t match_count) {
401f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpEvent** ppEvent = match_list;
402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
4032aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  while (match_count--) {
404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    JdwpEvent* pEvent = *ppEvent;
405872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
406872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    for (int i = 0; i < pEvent->modCount; i++) {
407872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
408bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")",
409bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                   pEvent->requestId);
410761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        UnregisterEvent(pEvent);
411872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        EventFree(pEvent);
412872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        break;
413872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
414872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
415872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
416872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    ppEvent++;
417872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
418872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
419f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  delete[] match_list;
420872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Match a string against a "restricted regular expression", which is just
424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
426872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ("Restricted name globbing" might have been a better term.)
427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
428761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic bool PatternMatch(const char* pattern, const std::string& target) {
429a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  size_t patLen = strlen(pattern);
430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (pattern[0] == '*') {
431872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    patLen--;
432a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    if (target.size() < patLen) {
433872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      return false;
434872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
435a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0;
436872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else if (pattern[patLen-1] == '*') {
437a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strncmp(pattern, target.c_str(), patLen-1) == 0;
438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
439a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes    return strcmp(pattern, target.c_str()) == 0;
440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See if the event's mods match up with the contents of "basket".
445872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
446872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we find a Count mod before rejecting an event, we decrement it.  We
447872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * need to do this even if later mods cause us to ignore the event.
448872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
449bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket)
450b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpEventMod* pMod = pEvent->mods;
452872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
453872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    switch (pMod->modKind) {
455872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_COUNT:
456872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK_GT(pMod->count.count, 0);
457872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      pMod->count.count--;
45843207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      if (pMod->count.count > 0) {
45943207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz        return false;
46043207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz      }
461872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
462872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CONDITIONAL:
463872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      CHECK(false);  // should not be getting these
464872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
465872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_THREAD_ONLY:
466bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->threadOnly.threadId != basket.threadId) {
467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
468872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_CLASS_ONLY:
471bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (!Dbg::MatchType(basket.classId, 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:
486bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->locationOnly.loc != *basket.pLoc) {
487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
488872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
489872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_EXCEPTION_ONLY:
491bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket.excepClassId, pMod->exceptionOnly.refTypeId)) {
492872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
493872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
494bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if ((basket.caught && !pMod->exceptionOnly.caught) || (!basket.caught && !pMod->exceptionOnly.uncaught)) {
495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
498872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_FIELD_ONLY:
499bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->fieldOnly.fieldId != basket.fieldId) {
500479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz        return false;
501479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz      }
502bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (!Dbg::MatchType(basket.fieldTypeID, pMod->fieldOnly.refTypeId)) {
503872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
506872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_STEP:
507bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->step.threadId != basket.threadId) {
508872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
509872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
510872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
511872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    case MK_INSTANCE_ONLY:
512bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (pMod->instanceOnly.objectId != basket.thisPtr) {
513872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes        return false;
514872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
515872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
516872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    default:
5177b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes      LOG(FATAL) << "unknown mod kind " << pMod->modKind;
518872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
521872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
522872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
523872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
524872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
525872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Find all events of type "eventKind" with mods that match up with the
526872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * rest of the arguments.
527872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
528f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes * Found events are appended to "match_list", and "*pMatchCount" is advanced,
529872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * so this may be called multiple times for grouped 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 */
534bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzvoid JdwpState::FindMatchingEvents(JdwpEventKind eventKind, const ModBasket& basket,
535bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                   JdwpEvent** match_list, size_t* pMatchCount) {
536872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* start after the existing entries */
537f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  match_list += *pMatchCount;
538872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
539bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) {
540761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    if (pEvent->eventKind == eventKind && ModsMatch(pEvent, basket)) {
541f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      *match_list++ = pEvent;
542872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      (*pMatchCount)++;
543872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
544872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
545872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
546872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
547872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
548872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Scan through the list of matches and determine the most severe
549872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspension policy.
550872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
551f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughesstatic JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** match_list, int match_count) {
552872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  JdwpSuspendPolicy policy = SP_NONE;
553872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
5542aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  while (match_count--) {
555f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    if ((*match_list)->suspend_policy > policy) {
556f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      policy = (*match_list)->suspend_policy;
557872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
558f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    match_list++;
559872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
560872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
561872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return policy;
562872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Three possibilities:
566872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_NONE - do nothing
567872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_EVENT_THREAD - suspend ourselves
568872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  SP_ALL - suspend everybody except JDWP support thread
569872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
57000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) {
571f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")";
572f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_NONE) {
573872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
574872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
575872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
576f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  if (suspend_policy == SP_ALL) {
577475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    Dbg::SuspendVM();
578872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
579f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CHECK_EQ(suspend_policy, SP_EVENT_THREAD);
580872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
581872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
582872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is rare but possible -- see CLASS_PREPARE handling */
58300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (thread_self_id == debug_thread_id_) {
584761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread";
585872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return;
586872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
587872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
588872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
589872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  while (true) {
590872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pReq->ready = true;
591872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::SuspendSelf();
592872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    pReq->ready = false;
593872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
594872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /*
595872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * The JDWP thread has told us (and possibly all other threads) to
596872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
597872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes     */
598d38667a055d507492fd05f78519a7e1f0b85ea03Sebastien Hertz    if (!pReq->invoke_needed) {
599761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      /*LOGD("SuspendByPolicy: no invoke needed");*/
600872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      break;
601872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
603872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    /* grab this before posting/suspending again */
60400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    SetWaitForEventThread(thread_self_id);
605872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
606d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes    /* leave pReq->invoke_needed_ raised so we can check reentrancy */
607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    Dbg::ExecuteMethod(pReq);
608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
609475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    pReq->error = ERR_NONE;
610872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
612872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
61300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy,
61400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              ObjectId threadId) {
61500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
61600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->AssertThreadSuspensionIsAllowable();
61700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  /* send request and possibly suspend ourselves */
61800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (pReq != NULL) {
61900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId();
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
62100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (suspend_policy != SP_NONE) {
62200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      SetWaitForEventThread(threadId);
62300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
62400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    EventFinish(pReq);
62500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    SuspendByPolicy(suspend_policy, thread_self_id);
62600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->TransitionFromSuspendedToRunnable();
62700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
62800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
62900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
630872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
631872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Determine if there is a method invocation in progress in the current
632872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread.
633872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
634475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq
635872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * state.  If set, we're in the process of invoking a method.
636872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
637761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::InvokeInProgress() {
638872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
639d38667a055d507492fd05f78519a7e1f0b85ea03Sebastien Hertz  return pReq->invoke_needed;
640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
641872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
642872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
643872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We need the JDWP thread to hold off on doing stuff while we post an
644872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event and then suspend ourselves.
645872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
646872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Call this with a threadId of zero if you just want to wait for the
647872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * current thread operation to complete.
648872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
649872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This could go to sleep waiting for another thread, so it's important
650872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that the thread be marked as VMWAIT before calling here.
651872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
652376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesvoid JdwpState::SetWaitForEventThread(ObjectId threadId) {
653872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  bool waited = false;
654872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
655872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* this is held for very brief periods; contention is unlikely */
65681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  Thread* self = Thread::Current();
65781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers  MutexLock mu(self, event_thread_lock_);
658872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
659872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
660872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If another thread is already doing stuff, wait for it.  This can
661872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * go to sleep indefinitely.
662872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
663a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  while (event_thread_id_ != 0) {
664d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping",
665d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers                               event_thread_id_, threadId);
666872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    waited = true;
667c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    event_thread_cond_.Wait(self);
668872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
669872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
670872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (waited || threadId != 0) {
671d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers    VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId);
672872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
673872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  if (threadId != 0) {
674a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes    event_thread_id_ = threadId;
675872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
677872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
678872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
679872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Clear the threadId and signal anybody waiting.
680872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
681376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesvoid JdwpState::ClearWaitForEventThread() {
682872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
683872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
684872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * function is called by dvmSuspendSelf(), and the transition back
685872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * to RUNNING would confuse it.
686872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
687c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  Thread* self = Thread::Current();
688c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  MutexLock mu(self, event_thread_lock_);
689872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
690a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  CHECK_NE(event_thread_id_, 0U);
691d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers  VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", event_thread_id_);
692872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
693a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  event_thread_id_ = 0;
694872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
695c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  event_thread_cond_.Signal(self);
696872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
697872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
698872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
699872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
700872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Prep an event.  Allocates storage for the message and leaves space for
701872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the header.
702872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
703872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstatic ExpandBuf* eventPrep() {
704872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = expandBufAlloc();
705872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAddSpace(pReq, kJDWPHeaderLen);
706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return pReq;
707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
708872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
709872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
710872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Write the header into the buffer and send the packet off to the debugger.
711872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Takes ownership of "pReq" (currently discards it).
713872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
714761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::EventFinish(ExpandBuf* pReq) {
715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t* buf = expandBufGetBuffer(pReq);
716872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
717f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(buf, expandBufGetLength(pReq));
718761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  Set4BE(buf+4, NextRequestSerial());
719f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(buf+8, 0);     /* flags */
720f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(buf+9, kJdwpEventCommandSet);
721f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(buf+10, kJdwpCompositeCommand);
722872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
72399660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // Prevents from interleaving commands and events. Otherwise we could end up in sending an event
72499660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // before sending the reply of the command being processed and would lead to bad synchronization
72599660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  // between the debugger and the debuggee.
72699660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz  WaitForProcessingRequest();
72799660e1c3d6117cfb8bac25b1a0413833ab15b2aSebastien Hertz
728761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  SendRequest(pReq);
729872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
730872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufFree(pReq);
731872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
732872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
733872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
734872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
735872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the debugger that we have finished initializing.  This is always
736872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * sent, even if the debugger hasn't requested it.
737872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
738872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This should be sent "before the main thread is started and before
739872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any application code has been executed".  The thread ID in the message
740872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * must be for the main thread.
741872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
742376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMStart() {
743f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpSuspendPolicy suspend_policy;
744872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ObjectId threadId = Dbg::GetThreadSelfId();
745872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
746376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughes  if (options_->suspend) {
747f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    suspend_policy = SP_ALL;
748872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  } else {
749f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    suspend_policy = SP_NONE;
750872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
751872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
752761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  ExpandBuf* pReq = eventPrep();
753761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
7547934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    MutexLock mu(Thread::Current(), event_list_lock_);  // probably don't need this here
755872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
7564dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "EVENT: " << EK_VM_START;
757f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
758872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
759f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    expandBufAdd1(pReq, suspend_policy);
760872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    expandBufAdd4BE(pReq, 1);
761872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
762872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    expandBufAdd1(pReq, EK_VM_START);
763872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    expandBufAdd4BE(pReq, 0);       /* requestId */
764872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    expandBufAdd8BE(pReq, threadId);
765872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
766872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
767138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
768138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
769872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* send request and possibly suspend ourselves */
77000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId);
771872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
772872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
773872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
774872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
775bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic void LogMatchingEventsAndThread(JdwpEvent** match_list, size_t match_count,
776bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                                       const ModBasket& basket)
777bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
778bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  for (size_t i = 0; i < match_count; ++i) {
779bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    JdwpEvent* pEvent = match_list[i];
780bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind
781bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz               << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
782bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
783bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  std::string thread_name;
784bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  JdwpError error = Dbg::GetThreadName(basket.threadId, thread_name);
785bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  if (error != JDWP::ERR_NONE) {
786bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    thread_name = "<unknown>";
787bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  }
788bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  VLOG(jdwp) << StringPrintf("  thread=%#" PRIx64, basket.threadId) << " " << thread_name;
789bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz}
790bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
791872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
792872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A location of interest has been reached.  This handles:
793872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Breakpoint
794872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   SingleStep
795872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodEntry
796872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   MethodExit
797872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * These four types must be grouped together in a single response.  The
798872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "eventFlags" indicates the type of event(s) that have happened.
799872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
800872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
801872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
802872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   LocationOnly (for breakpoint/step only)
803872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *   Step (for step only)
804872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
805872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Interesting test cases:
806872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
807872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
808872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
809872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  - Single-step to a line with a breakpoint.  Should get a single
810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    event message with both events in it.
811872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
812579b02416e05e32e535126e1ed61613a2cdb030eJeff Haobool JdwpState::PostLocationEvent(const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags,
813579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao                                  const JValue* returnValue) {
814872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
815872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pLoc;
816748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  basket.classId = pLoc->class_id;
817872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
818872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.threadId = Dbg::GetThreadSelfId();
819748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  basket.className = Dbg::GetClassName(pLoc->class_id);
820872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
821872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
822872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * On rare occasions we may need to execute interpreted code in the VM
823872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while handling a request from the debugger.  Don't fire breakpoints
824872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * while doing so.  (I don't think we currently do this at all, so
825872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this is mostly paranoia.)
826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
827a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes  if (basket.threadId == debug_thread_id_) {
8284dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Ignoring location event in JDWP thread";
829872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return false;
830872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
831872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
832872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
833872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * The debugger variable display tab may invoke the interpreter to format
834872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * complex objects.  We want to ignore breakpoints and method entry/exit
835872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * traps while working on behalf of the debugger.
836872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   *
837872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * If we don't ignore them, the VM will get hung up, because we'll
838872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * suspend on a breakpoint while the debugger is still waiting for its
839872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * method invocation to complete.
840872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
841761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
8424dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")";
843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return false;
844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
845872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
846bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  size_t match_count = 0;
847872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = NULL;
848f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpSuspendPolicy suspend_policy = SP_NONE;
849761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
85050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(Thread::Current(), event_list_lock_);
851138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    JdwpEvent** match_list = AllocMatchList(event_list_size_);
8528696433d1b3d8ba15288483b777edd888de69135Elliott Hughes    if ((eventFlags & Dbg::kBreakpoint) != 0) {
853bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_BREAKPOINT, basket, match_list, &match_count);
854761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
855761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    if ((eventFlags & Dbg::kSingleStep) != 0) {
856bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_SINGLE_STEP, basket, match_list, &match_count);
857761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
858761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    if ((eventFlags & Dbg::kMethodEntry) != 0) {
859bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_METHOD_ENTRY, basket, match_list, &match_count);
860761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
861761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    if ((eventFlags & Dbg::kMethodExit) != 0) {
862bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_METHOD_EXIT, basket, match_list, &match_count);
863bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, match_list, &match_count);
864761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes    }
8652aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes    if (match_count != 0) {
866f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      suspend_policy = scanSuspendPolicy(match_list, match_count);
867bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
868bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (VLOG_IS_ON(jdwp)) {
869bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        LogMatchingEventsAndThread(match_list, match_count, basket);
870bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  location=" << *pLoc;
871bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, basket.thisPtr);
872bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
873bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      }
874872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
875761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      pReq = eventPrep();
876f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      expandBufAdd1(pReq, suspend_policy);
8772aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes      expandBufAdd4BE(pReq, match_count);
878761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes
879bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      for (size_t i = 0; i < match_count; i++) {
880f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd1(pReq, match_list[i]->eventKind);
881f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd4BE(pReq, match_list[i]->requestId);
882761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd8BE(pReq, basket.threadId);
8836e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes        expandBufAddLocation(pReq, *pLoc);
884579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao        if (match_list[i]->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) {
885579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao          Dbg::OutputMethodReturnValue(pLoc->method_id, returnValue, pReq);
886579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao        }
887761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      }
888872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
889872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
890f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CleanupMatchList(match_list, match_count);
891761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  }
892872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
893138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
894138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
89500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
8962aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  return match_count != 0;
897872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
898872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
8993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertzbool JdwpState::PostFieldEvent(const JdwpLocation* pLoc, RefTypeId typeId, FieldId fieldId,
9003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                               ObjectId thisPtr, const JValue* fieldValue, bool is_modification) {
9013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  ModBasket basket;
9023f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.pLoc = pLoc;
9033f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.classId = pLoc->class_id;
9043f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.thisPtr = thisPtr;
9053f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.threadId = Dbg::GetThreadSelfId();
9063f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  basket.className = Dbg::GetClassName(pLoc->class_id);
907479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz  basket.fieldTypeID = typeId;
908479fc1ecc12fa6560ca90d841c4d5174fb346618Sebastien Hertz  basket.fieldId = fieldId;
9093f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
910bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  DCHECK_EQ(fieldValue != nullptr, is_modification);
911bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
9123f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (InvokeInProgress()) {
9133f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    VLOG(jdwp) << "Not posting field event during invoke";
9143f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return false;
9153f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9163f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9173f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Get field's reference type tag.
9183f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  JDWP::JdwpTypeTag type_tag;
9193f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  uint32_t class_status;  // unused here.
9203f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  JdwpError error = Dbg::GetClassInfo(typeId, &type_tag, &class_status, NULL);
9213f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (error != ERR_NONE) {
9223f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return false;
9233f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9243f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9253f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Get instance type tag.
9263f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  uint8_t tag;
9273f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  error = Dbg::GetObjectTag(thisPtr, tag);
9283f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  if (error != ERR_NONE) {
9293f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return false;
9303f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9313f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
932bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  size_t match_count = 0;
9333f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  ExpandBuf* pReq = NULL;
9343f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  JdwpSuspendPolicy suspend_policy = SP_NONE;
9353f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  {
9363f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    MutexLock mu(Thread::Current(), event_list_lock_);
9373f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    JdwpEvent** match_list = AllocMatchList(event_list_size_);
9383f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9393f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (is_modification) {
940bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_FIELD_MODIFICATION, basket, match_list, &match_count);
9413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    } else {
942bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_FIELD_ACCESS, basket, match_list, &match_count);
9433f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
9443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (match_count != 0) {
9453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      suspend_policy = scanSuspendPolicy(match_list, match_count);
946bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
947bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (VLOG_IS_ON(jdwp)) {
948bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        LogMatchingEventsAndThread(match_list, match_count, basket);
949bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  location=" << *pLoc;
950bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, basket.thisPtr);
951bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, basket.fieldTypeID) << " "
952bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                   << Dbg::GetClassName(basket.fieldTypeID);
953bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  field=%#" PRIx32, basket.fieldId) << " "
954bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                   << Dbg::GetFieldName(basket.fieldId);
955bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
956bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      }
9573f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9583f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      pReq = eventPrep();
9593f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      expandBufAdd1(pReq, suspend_policy);
9603f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      expandBufAdd4BE(pReq, match_count);
9613f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
962bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      for (size_t i = 0; i < match_count; i++) {
9633f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAdd1(pReq, match_list[i]->eventKind);
9643f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAdd4BE(pReq, match_list[i]->requestId);
9653f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAdd8BE(pReq, basket.threadId);
9663f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAddLocation(pReq, *pLoc);
9673f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAdd1(pReq, type_tag);
9683f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAddRefTypeId(pReq, typeId);
9693f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAddFieldId(pReq, fieldId);
9703f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAdd1(pReq, tag);
9713f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        expandBufAddObjectId(pReq, thisPtr);
9723f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        if (is_modification) {
9733f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz          Dbg::OutputFieldValue(fieldId, fieldValue, pReq);
9743f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz        }
9753f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      }
9763f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
9773f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9783f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    CleanupMatchList(match_list, match_count);
9793f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
9803f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9813f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  Dbg::ManageDeoptimization();
9823f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9833f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
9843f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  return match_count != 0;
9853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz}
9863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
987872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
988872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A thread is starting or stopping.
989872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
990872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
991872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly
992872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
993234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughesbool JdwpState::PostThreadChange(ObjectId threadId, bool start) {
994872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK_EQ(threadId, Dbg::GetThreadSelfId());
995872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
996872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
997872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * I don't think this can happen.
998872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
999761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
1000872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    LOG(WARNING) << "Not posting thread change during invoke";
1001872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return false;
1002872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1003872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1004872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
1005872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.threadId = threadId;
1006872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1007872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = NULL;
1008f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpSuspendPolicy suspend_policy = SP_NONE;
1009bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  size_t match_count = 0;
1010234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  {
1011234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes    // Don't allow the list to be updated while we scan it.
101250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(Thread::Current(), event_list_lock_);
1013f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    JdwpEvent** match_list = AllocMatchList(event_list_size_);
1014234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
1015234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes    if (start) {
1016bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_THREAD_START, basket, match_list, &match_count);
1017234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes    } else {
1018bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      FindMatchingEvents(EK_THREAD_DEATH, basket, match_list, &match_count);
1019234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes    }
1020872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10212aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes    if (match_count != 0) {
1022f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      suspend_policy = scanSuspendPolicy(match_list, match_count);
1023bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
1024bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (VLOG_IS_ON(jdwp)) {
1025bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        LogMatchingEventsAndThread(match_list, match_count, basket);
1026bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1027bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      }
1028872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1029234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes      pReq = eventPrep();
1030f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      expandBufAdd1(pReq, suspend_policy);
10312aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes      expandBufAdd4BE(pReq, match_count);
1032234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
1033bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      for (size_t i = 0; i < match_count; i++) {
1034f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd1(pReq, match_list[i]->eventKind);
1035f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd4BE(pReq, match_list[i]->requestId);
1036234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes        expandBufAdd8BE(pReq, basket.threadId);
1037234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes      }
1038872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
1039872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1040f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CleanupMatchList(match_list, match_count);
1041234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  }
1042872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1043138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1044138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
104500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
1046872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
10472aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  return match_count != 0;
1048872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1049872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1050872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1051872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send a polite "VM is dying" message to the debugger.
1052872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1053872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Skips the usual "event token" stuff.
1054872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1055376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMDeath() {
10564dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  VLOG(jdwp) << "EVENT: " << EK_VM_DEATH;
1057872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1058872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = eventPrep();
1059872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, SP_NONE);
1060872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 1);
1061872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1062872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd1(pReq, EK_VM_DEATH);
1063872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  expandBufAdd4BE(pReq, 0);
1064761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  EventFinish(pReq);
1065872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  return true;
1066872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1067872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1068872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1069872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * An exception has been thrown.  It may or may not have been caught.
1070872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1071872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1072872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
1073872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *    ExceptionOnly, InstanceOnly
1074872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1075872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The "exceptionId" has not been added to the GC-visible object registry,
1076872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * because there's a pretty good chance that we're not going to send it
1077872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * up the debugger.
1078872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1079761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::PostException(const JdwpLocation* pThrowLoc,
1080748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes                              ObjectId exceptionId, RefTypeId exceptionClassId,
1081748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes                              const JdwpLocation* pCatchLoc, ObjectId thisPtr) {
1082872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
1083872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1084872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.pLoc = pThrowLoc;
1085748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  basket.classId = pThrowLoc->class_id;
1086872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.threadId = Dbg::GetThreadSelfId();
1087c308a5d8c1993ff51be355531548e91409bdbd82Elliott Hughes  basket.className = Dbg::GetClassName(basket.classId);
1088872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.excepClassId = exceptionClassId;
1089748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  basket.caught = (pCatchLoc->class_id != 0);
1090872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.thisPtr = thisPtr;
1091872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1092872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* don't try to post an exception caused by the debugger */
1093761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
10944dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")";
1095872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return false;
1096872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1097872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1098bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  size_t match_count = 0;
1099872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = NULL;
1100f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpSuspendPolicy suspend_policy = SP_NONE;
1101761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
110250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(Thread::Current(), event_list_lock_);
1103138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz    JdwpEvent** match_list = AllocMatchList(event_list_size_);
1104bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    FindMatchingEvents(EK_EXCEPTION, basket, match_list, &match_count);
11052aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes    if (match_count != 0) {
1106f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      suspend_policy = scanSuspendPolicy(match_list, match_count);
1107bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
1108bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (VLOG_IS_ON(jdwp)) {
1109bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        LogMatchingEventsAndThread(match_list, match_count, basket);
1110bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  throwLocation=" << *pThrowLoc;
1111bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        if (pCatchLoc->class_id == 0) {
1112bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz          VLOG(jdwp) << "  catchLocation=uncaught";
1113bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        } else {
1114bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz          VLOG(jdwp) << "  catchLocation=" << *pCatchLoc;
1115bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        }
1116bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  this=%#" PRIx64, basket.thisPtr);
1117bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  exceptionClass=%#" PRIx64, basket.excepClassId) << " "
1118bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz                   << Dbg::GetClassName(basket.excepClassId);
1119bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1120bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      }
1121872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1122761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      pReq = eventPrep();
1123f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      expandBufAdd1(pReq, suspend_policy);
11242aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes      expandBufAdd4BE(pReq, match_count);
1125761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes
1126bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      for (size_t i = 0; i < match_count; i++) {
1127f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd1(pReq, match_list[i]->eventKind);
1128f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd4BE(pReq, match_list[i]->requestId);
1129761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd8BE(pReq, basket.threadId);
1130872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11316e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes        expandBufAddLocation(pReq, *pThrowLoc);
1132761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd1(pReq, JT_OBJECT);
1133761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd8BE(pReq, exceptionId);
11346e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes        expandBufAddLocation(pReq, *pCatchLoc);
1135761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      }
1136872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
1137872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1138f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CleanupMatchList(match_list, match_count);
1139872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1140872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1141138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1142138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
114300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
1144872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
11452aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  return match_count != 0;
1146872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1147872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1148872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1149872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Announce that a class has been loaded.
1150872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1151872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods:
1152872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
1153872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
115400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool JdwpState::PostClassPrepare(JdwpTypeTag tag, RefTypeId refTypeId, const std::string& signature,
115500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                 int status) {
1156872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ModBasket basket;
1157872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1158872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.classId = refTypeId;
1159872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  basket.threadId = Dbg::GetThreadSelfId();
1160c308a5d8c1993ff51be355531548e91409bdbd82Elliott Hughes  basket.className = Dbg::GetClassName(basket.classId);
1161872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1162872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* suppress class prep caused by debugger */
1163761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  if (InvokeInProgress()) {
11644dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")";
1165872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    return false;
1166872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1167872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1168872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  ExpandBuf* pReq = NULL;
1169f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JdwpSuspendPolicy suspend_policy = SP_NONE;
1170bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz  size_t match_count = 0;
1171761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  {
117250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(Thread::Current(), event_list_lock_);
1173f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    JdwpEvent** match_list = AllocMatchList(event_list_size_);
1174bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz    FindMatchingEvents(EK_CLASS_PREPARE, basket, match_list, &match_count);
11752aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes    if (match_count != 0) {
1176f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      suspend_policy = scanSuspendPolicy(match_list, match_count);
1177bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz
1178bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      if (VLOG_IS_ON(jdwp)) {
1179bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        LogMatchingEventsAndThread(match_list, match_count, basket);
1180bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << StringPrintf("  type=%#" PRIx64, basket.classId)<< " " << signature;
1181bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz        VLOG(jdwp) << "  suspend_policy=" << suspend_policy;
1182bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      }
1183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1184a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes      if (basket.threadId == debug_thread_id_) {
1185761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        /*
1186761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes         * JDWP says that, for a class prep in the debugger thread, we
1187761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes         * should set threadId to null and if any threads were supposed
1188761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes         * to be suspended then we suspend all other threads.
1189761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes         */
11904dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes        VLOG(jdwp) << "  NOTE: class prepare in debugger thread!";
1191761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        basket.threadId = 0;
1192f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        if (suspend_policy == SP_EVENT_THREAD) {
1193f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes          suspend_policy = SP_ALL;
1194761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        }
1195872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes      }
1196872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1197761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      pReq = eventPrep();
1198f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes      expandBufAdd1(pReq, suspend_policy);
11992aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes      expandBufAdd4BE(pReq, match_count);
1200872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1201bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz      for (size_t i = 0; i < match_count; i++) {
1202f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd1(pReq, match_list[i]->eventKind);
1203f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes        expandBufAdd4BE(pReq, match_list[i]->requestId);
1204761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd8BE(pReq, basket.threadId);
1205872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1206761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd1(pReq, tag);
1207761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd8BE(pReq, refTypeId);
1208761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAddUtf8String(pReq, signature);
1209761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes        expandBufAdd4BE(pReq, status);
1210761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes      }
1211872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    }
1212f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    CleanupMatchList(match_list, match_count);
1213872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1214872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1215138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  Dbg::ManageDeoptimization();
1216138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
121700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  SendRequestAndPossiblySuspend(pReq, suspend_policy, basket.threadId);
1218872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
12192aa2e39548e194c5514d6534149ca1078021eab1Elliott Hughes  return match_count != 0;
1220872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1221872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1222872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
1223872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send up a chunk of DDM data.
1224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes *
1225872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * While this takes the form of a JDWP "event", it doesn't interact with
1226872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * other debugger traffic, and can't suspend the VM, so we skip all of
1227872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the fun event token gymnastics.
1228872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
1229cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughesvoid JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
1230872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  uint8_t header[kJDWPHeaderLen + 8];
1231872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  size_t dataLen = 0;
1232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1233872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  CHECK(iov != NULL);
1234cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_GT(iov_count, 0);
1235cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  CHECK_LT(iov_count, 10);
1236872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
1238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
1239872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * this by creating a new copy of the vector with space for the header.
1240872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
1241f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  std::vector<iovec> wrapiov;
1242f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom  wrapiov.push_back(iovec());
1243cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes  for (int i = 0; i < iov_count; i++) {
1244f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    wrapiov.push_back(iov[i]);
1245872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    dataLen += iov[i].iov_len;
1246872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  }
1247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /* form the header (JDWP plus DDMS) */
1249f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(header, sizeof(header) + dataLen);
1250f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(header+4, NextRequestSerial());
1251f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(header+8, 0);     /* flags */
1252f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(header+9, kJDWPDdmCmdSet);
1253f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set1(header+10, kJDWPDdmCmd);
1254f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(header+11, type);
1255f7c3b6625d710a8700325eea447f65e9f963b7f2Elliott Hughes  Set4BE(header+15, dataLen);
1256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_base = header;
1258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  wrapiov[0].iov_len = sizeof(header);
1259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
126015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level
126115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  // than mutator for lock ordering reasons.
126200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread* self = Thread::Current();
126362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self);
126462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (safe_to_release_mutator_lock_over_send) {
126538f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom    for (size_t i = 0; i < kMutatorLock; ++i) {
126662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      if (self->GetHeldMutex(static_cast<LockLevel>(i)) != NULL) {
126762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        safe_to_release_mutator_lock_over_send = false;
126862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        break;
126962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      }
127015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    }
127115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
127215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  if (safe_to_release_mutator_lock_over_send) {
127315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Change state to waiting to allow GC, ... while we're sending.
127415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
1275f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
127615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    self->TransitionFromSuspendedToRunnable();
127715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  } else {
127815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers    // Send and possibly block GC...
1279f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom    SendBufferedRequest(type, wrapiov);
128015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers  }
1281872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}
1282872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1283872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace JDWP
1284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
1285872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace art
1286