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