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 */
16872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
17872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
18872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Dalvik-specific side of debugger support.  (The JDWP code is intended to
19872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * be relatively generic.)
20872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
21fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_DEBUGGER_H_
22fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_DEBUGGER_H_
23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
24872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <pthread.h>
25872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
2661b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz#include <set>
273bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes#include <string>
284d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz#include <vector>
293bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes
30e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier#include "gc_root.h"
310f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe#include "class_linker.h"
320f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe#include "handle.h"
33872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp.h"
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "jni.h"
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "jvalue.h"
363398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier#include "obj_ptr.h"
3799170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang#include "thread.h"
38920af3e556c730a5fbdab90a6d0ec1a2dbe8940bJeff Hao#include "thread_state.h"
39872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art {
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Class;
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Object;
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Throwable;
452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
46c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierclass ArtField;
47e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod;
486995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzclass ObjectRegistry;
49cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertzclass ScopedObjectAccess;
506995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzclass ScopedObjectAccessUnchecked;
518009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertzclass StackVisitor;
521b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogersclass Thread;
53872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/*
55872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Invoke-during-breakpoint support.
56872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */
57872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct DebugInvokeReq {
58cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  DebugInvokeReq(uint32_t invoke_request_id, JDWP::ObjectId invoke_thread_id,
59cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                 mirror::Object* invoke_receiver, mirror::Class* invoke_class,
60e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                 ArtMethod* invoke_method, uint32_t invoke_options,
61cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                 uint64_t args[], uint32_t args_count)
62cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz      : request_id(invoke_request_id), thread_id(invoke_thread_id), receiver(invoke_receiver),
63cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz        klass(invoke_class), method(invoke_method), arg_count(args_count), arg_values(args),
64cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz        options(invoke_options), reply(JDWP::expandBufAlloc()) {
65475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  }
66475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
67cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  ~DebugInvokeReq() {
68cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz    JDWP::expandBufFree(reply);
69cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  }
70cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
71cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Request
72cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  const uint32_t request_id;
73cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  const JDWP::ObjectId thread_id;
74cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  GcRoot<mirror::Object> receiver;      // not used for ClassType.InvokeMethod.
751558b577907b613864e98f05862543557263e864Sebastien Hertz  GcRoot<mirror::Class> klass;
76cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  ArtMethod* const method;
771558b577907b613864e98f05862543557263e864Sebastien Hertz  const uint32_t arg_count;
78cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  std::unique_ptr<uint64_t[]> arg_values;   // will be null if arg_count_ == 0. We take ownership
79cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                                            // of this array so we must delete it upon destruction.
801558b577907b613864e98f05862543557263e864Sebastien Hertz  const uint32_t options;
81872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
82cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Reply
83cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  JDWP::ExpandBuf* const reply;
8461b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
85bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  void VisitRoots(RootVisitor* visitor, const RootInfo& root_info)
86bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
873b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier
8861b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz private:
8961b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  DISALLOW_COPY_AND_ASSIGN(DebugInvokeReq);
9061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz};
9161b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
9261b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz// Thread local data-structure that holds fields for controlling single-stepping.
93597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertzclass SingleStepControl {
94597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz public:
95597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  SingleStepControl(JDWP::JdwpStepSize step_size, JDWP::JdwpStepDepth step_depth,
96e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                    int stack_depth, ArtMethod* method)
97597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz      : step_size_(step_size), step_depth_(step_depth),
98597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz        stack_depth_(stack_depth), method_(method) {
9961b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  }
10061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
101597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  JDWP::JdwpStepSize GetStepSize() const {
102597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz    return step_size_;
103597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  }
10461b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
105597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  JDWP::JdwpStepDepth GetStepDepth() const {
106597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz    return step_depth_;
107597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  }
10861b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
109597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  int GetStackDepth() const {
110597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz    return stack_depth_;
111597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  }
11261b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
113e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* GetMethod() const {
114e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    return method_;
115597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  }
116597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
117597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  const std::set<uint32_t>& GetDexPcs() const {
118597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz    return dex_pcs_;
119597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  }
12061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz
121597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  void AddDexPc(uint32_t dex_pc);
122bb43b433c845e253a11346f0f03706d58a44f23cSebastien Hertz
123597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  bool ContainsDexPc(uint32_t dex_pc) const;
124bb43b433c845e253a11346f0f03706d58a44f23cSebastien Hertz
12561b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz private:
126597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // See JdwpStepSize and JdwpStepDepth for details.
127597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  const JDWP::JdwpStepSize step_size_;
128597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  const JDWP::JdwpStepDepth step_depth_;
129597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
130597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // The stack depth when this single-step was initiated. This is used to support SD_OVER and SD_OUT
131597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // single-step depth.
132597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  const int stack_depth_;
133597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
134597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // The location this single-step was initiated from.
135597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // A single-step is initiated in a suspended thread. We save here the current method and the
136597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // set of DEX pcs associated to the source line number where the suspension occurred.
137597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // This is used to support SD_INTO and SD_OVER single-step depths so we detect when a single-step
138597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  // causes the execution of an instruction in a different method or at a different line number.
139e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method_;
140e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
141597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz  std::set<uint32_t> dex_pcs_;
142597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz
14361b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  DISALLOW_COPY_AND_ASSIGN(SingleStepControl);
144872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes};
145872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
14642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz// TODO rename to InstrumentationRequest.
1470ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchiclass DeoptimizationRequest {
1480ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi public:
1494d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  enum Kind {
1504d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz    kNothing,                   // no action.
15142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    kRegisterForEvent,          // start listening for instrumentation event.
15242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz    kUnregisterForEvent,        // stop listening for instrumentation event.
1534d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz    kFullDeoptimization,        // deoptimize everything.
1544d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz    kFullUndeoptimization,      // undeoptimize everything.
1554d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz    kSelectiveDeoptimization,   // deoptimize one method.
1564d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz    kSelectiveUndeoptimization  // undeoptimize one method.
1574d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  };
1584d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
1590ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  DeoptimizationRequest() : kind_(kNothing), instrumentation_event_(0), method_(nullptr) {}
1600ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
1610ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  DeoptimizationRequest(const DeoptimizationRequest& other)
162bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_)
1630ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi      : kind_(other.kind_), instrumentation_event_(other.instrumentation_event_) {
1640ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    // Create a new JNI global reference for the method.
1650ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    SetMethod(other.Method());
1660ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  }
1670ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
168bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  ArtMethod* Method() const REQUIRES_SHARED(Locks::mutator_lock_);
1690ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
170bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void SetMethod(ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_);
1710ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
1720ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  // Name 'Kind()' would collide with the above enum name.
1730ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  Kind GetKind() const {
1740ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    return kind_;
1750ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  }
1760ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
1770ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  void SetKind(Kind kind) {
1780ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    kind_ = kind;
1790ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  }
1804d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
1810ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  uint32_t InstrumentationEvent() const {
1820ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    return instrumentation_event_;
1830ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  }
1844d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
1850ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  void SetInstrumentationEvent(uint32_t instrumentation_event) {
1860ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi    instrumentation_event_ = instrumentation_event;
1870ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  }
1880ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi
1890ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi private:
1900ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  Kind kind_;
1914d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
19242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // TODO we could use a union to hold the instrumentation_event and the method since they
19342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // respectively have sense only for kRegisterForEvent/kUnregisterForEvent and
19442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // kSelectiveDeoptimization/kSelectiveUndeoptimization.
19542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
19642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // Event to start or stop listening to. Only for kRegisterForEvent and kUnregisterForEvent.
1970ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  uint32_t instrumentation_event_;
19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
1994d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Method for selective deoptimization.
2000ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi  jmethodID method_;
2014d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz};
2026a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstd::ostream& operator<<(std::ostream& os, const DeoptimizationRequest::Kind& rhs);
2034d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
204872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesclass Dbg {
205ff17f1fd3ff32f93e45588eb2b158832d73f9afaElliott Hughes public:
2064ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes  static void SetJdwpAllowed(bool allowed);
207eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu  static bool IsJdwpAllowed();
2084ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes
209b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz  static void StartJdwp();
210d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes  static void StopJdwp();
211d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes
212767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  // Invoked by the GC in case we need to keep DDMS informed.
21390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  static void GcDidFinish() REQUIRES(!Locks::mutator_lock_);
214767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes
215872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  // Return the DebugInvokeReq for the current thread.
216872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  static DebugInvokeReq* GetInvokeReq();
217872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
218475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  static Thread* GetDebugThread();
219475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  static void ClearWaitForEventThread();
220475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
221872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
222872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Enable/disable breakpoints and step modes.  Used to provide a heads-up
223872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * when the debugger attaches.
224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
225872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  static void Connected();
226138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  static void GoActive()
22790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::breakpoint_lock_, !Locks::deoptimization_lock_, !Locks::mutator_lock_);
22890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  static void Disconnected() REQUIRES(!Locks::deoptimization_lock_, !Locks::mutator_lock_);
2294e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  static void Dispose() {
2304e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz    gDisposed = true;
2314e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  }
232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
233c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  // Returns true if we're actually debugging with a real debugger, false if it's
234c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  // just DDMS (or nothing at all).
235eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  static bool IsDebuggerActive() {
236eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    return gDebuggerActive;
237eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  }
238872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
239b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz  // Configures JDWP with parsed command-line options.
240b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz  static void ConfigureJdwp(const JDWP::JdwpOptions& jdwp_options);
241b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz
242c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  // Returns true if we had -Xrunjdwp or -agentlib:jdwp= on the command line.
243c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes  static bool IsJdwpConfigured();
244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
245d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier  // Returns true if a method has any breakpoints.
246e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool MethodHasAnyBreakpoints(ArtMethod* method)
247bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::breakpoint_lock_);
248d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier
2494e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  static bool IsDisposed() {
2504e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz    return gDisposed;
2514e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  }
2528696433d1b3d8ba15288483b777edd888de69135Elliott Hughes
253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Time, in milliseconds, since the last debugger activity.  Does not
255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * include DDMS activity.  Returns -1 if there has been no activity.
256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Returns 0 if we're in the middle of handling a debugger request.
257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  static int64_t LastDebuggerActivity();
259872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
260253fa555d9424a56c52879449eabe73d5c96cf61Sebastien Hertz  static void UndoDebuggerSuspensions()
26190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
262872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
264872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Class, Object, Array
265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
26600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static std::string GetClassName(JDWP::RefTypeId id)
267bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
2686995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static std::string GetClassName(mirror::Class* klass)
269bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
270c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId* class_object_id)
271bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
272c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId* superclass_id)
273bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
27400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
275bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
27600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
277bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
27888d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply)
279bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
280c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static void GetClassList(std::vector<JDWP::RefTypeId>* classes)
281bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
28288d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
28300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                      uint32_t* pStatus, std::string* pDescriptor)
284bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
285c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>* ids)
286bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
28764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes  static JDWP::JdwpError GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
288bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
289fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogers  static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
290bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
29124d3e46ea954cf3a35a2b57be2bf61864ee4f967Orion Hodson  static JDWP::JdwpError GetSourceDebugExtension(JDWP::RefTypeId ref_type_id,
29224d3e46ea954cf3a35a2b57be2bf61864ee4f967Orion Hodson                                                 std::string* extension_data)
29324d3e46ea954cf3a35a2b57be2bf61864ee4f967Orion Hodson      REQUIRES_SHARED(Locks::mutator_lock_);
294c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string* source_file)
295bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
296c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag)
297bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
298aed4be94da51b4fbb54c728151f0daf11535f6abElliott Hughes  static size_t GetTagWidth(JDWP::JdwpTag tag);
299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
300c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetArrayLength(JDWP::ObjectId array_id, int32_t* length)
301bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
30288d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError OutputArray(JDWP::ObjectId array_id, int offset, int count,
30300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                     JDWP::ExpandBuf* pReply)
304bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
30588d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
306c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                          JDWP::Request* request)
307bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
30800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3092c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz  static JDWP::JdwpError CreateString(const std::string& str, JDWP::ObjectId* new_string_id)
310bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3112c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz  static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object_id)
312bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
31388d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
3142c3e77a0b91b2225fcdd3b34d8a734b85eec0579Sebastien Hertz                                           JDWP::ObjectId* new_array_id)
315bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
31600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3176995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  //
3186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  // Event filtering.
3196995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  //
3206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static bool MatchThread(JDWP::ObjectId expected_thread_id, Thread* event_thread)
321bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
3236995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static bool MatchLocation(const JDWP::JdwpLocation& expected_location,
3246995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz                            const JDWP::EventLocation& event_location)
325bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3266995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
3273398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  static bool MatchType(ObjPtr<mirror::Class> event_class, JDWP::RefTypeId class_id)
328bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3296995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
3306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static bool MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
331c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                         ArtField* event_field)
332bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
3346995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static bool MatchInstance(JDWP::ObjectId expected_instance_id, mirror::Object* event_instance)
335bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
336872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
337ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  //
338ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  // Monitors.
339ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  //
340ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  static JDWP::JdwpError GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
341bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
342ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id,
343c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                          std::vector<JDWP::ObjectId>* monitors,
344c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                          std::vector<uint32_t>* stack_depths)
345bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
34652d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static JDWP::JdwpError GetContendedMonitor(JDWP::ObjectId thread_id,
347c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                             JDWP::ObjectId* contended_monitor)
348bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
349ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes
350ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  //
351ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  // Heap.
352ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  //
353ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes  static JDWP::JdwpError GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
354c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                           std::vector<uint64_t>* counts)
355bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3563b78c949ab839d21454bc6f18c7640d2ae8c22f3Elliott Hughes  static JDWP::JdwpError GetInstances(JDWP::RefTypeId class_id, int32_t max_count,
357c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                      std::vector<JDWP::ObjectId>* instances)
358bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3590cbaff584244ee767027aff35cd3c625aaee2994Elliott Hughes  static JDWP::JdwpError GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
360c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                             std::vector<JDWP::ObjectId>* referring_objects)
361bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
36264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes  static JDWP::JdwpError DisableCollection(JDWP::ObjectId object_id)
363bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
36464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes  static JDWP::JdwpError EnableCollection(JDWP::ObjectId object_id)
365bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
366c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError IsCollected(JDWP::ObjectId object_id, bool* is_collected)
367bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
36864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes  static void DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
369bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
370ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes
3719777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes  //
3729777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes  // Methods and fields.
3739777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes  //
374a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes  static std::string GetMethodName(JDWP::MethodId method_id)
375bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
376e3f991ff5751960a6b190720fac58a744cf4902dAlex Light  static bool IsMethodObsolete(JDWP::MethodId method_id)
377e3f991ff5751960a6b190720fac58a744cf4902dAlex Light      REQUIRES_SHARED(Locks::mutator_lock_);
37888d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId ref_type_id, bool with_generic,
37900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                              JDWP::ExpandBuf* pReply)
380bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
38188d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId ref_type_id, bool with_generic,
38200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                               JDWP::ExpandBuf* pReply)
383bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
38488d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId ref_type_id,
38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                  JDWP::ExpandBuf* pReply)
386bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
38788d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static void OutputLineTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId method_id,
38800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                              JDWP::ExpandBuf* pReply)
389bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
39088d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static void OutputVariableTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId id, bool with_generic,
39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                  JDWP::ExpandBuf* pReply)
392bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
393579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao  static void OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return_value,
394579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao                                      JDWP::ExpandBuf* pReply)
395bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3963f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  static void OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
3973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                               JDWP::ExpandBuf* pReply)
398bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
3999777ba230c83a0edcbda2cf7b208339e77bf171bElliott Hughes  static JDWP::JdwpError GetBytecodes(JDWP::RefTypeId class_id, JDWP::MethodId method_id,
400c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers                                      std::vector<uint8_t>* bytecodes)
401bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
40200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
403a96836a4115ad08762567c10bd4d198c5b644985Elliott Hughes  static std::string GetFieldName(JDWP::FieldId field_id)
404bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
40588d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId field_id)
406bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
40788d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId field_id)
408bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
40988d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError GetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
41000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                       JDWP::ExpandBuf* pReply)
411bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
41288d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError SetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
41300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                       uint64_t value, int width)
414bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
41588d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id,
41600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                             JDWP::ExpandBuf* pReply)
417bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
41888d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId field_id, uint64_t value, int width)
419bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
42000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
421b0b0b496125c16620e99ea4e4a05693c281eccf1Sebastien Hertz  static JDWP::JdwpError StringToUtf8(JDWP::ObjectId string_id, std::string* str)
422bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
423579b02416e05e32e535126e1ed61613a2cdb030eJeff Hao  static void OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::ExpandBuf* pReply)
424bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
426872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Thread, ThreadGroup, Frame
428872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
429c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetThreadName(JDWP::ObjectId thread_id, std::string* name)
430bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::thread_list_lock_);
43152d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply)
432bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::thread_list_lock_);
433a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz  static JDWP::JdwpError GetThreadGroupName(JDWP::ObjectId thread_group_id,
434a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz                                            JDWP::ExpandBuf* pReply)
435bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
436a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz  static JDWP::JdwpError GetThreadGroupParent(JDWP::ObjectId thread_group_id,
437a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz                                              JDWP::ExpandBuf* pReply)
438bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
439a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz  static JDWP::JdwpError GetThreadGroupChildren(JDWP::ObjectId thread_group_id,
440a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz                                                JDWP::ExpandBuf* pReply)
441bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
44200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static JDWP::ObjectId GetSystemThreadGroupId()
443bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
445920af3e556c730a5fbdab90a6d0ec1a2dbe8940bJeff Hao  static JDWP::JdwpThreadStatus ToJdwpThreadStatus(ThreadState state);
44652d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static JDWP::JdwpError GetThreadStatus(JDWP::ObjectId thread_id,
44752d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz                                         JDWP::JdwpThreadStatus* pThreadStatus,
44852d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz                                         JDWP::JdwpSuspendStatus* pSuspendStatus)
44990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_);
45052d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static JDWP::JdwpError GetThreadDebugSuspendCount(JDWP::ObjectId thread_id,
45152d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz                                                    JDWP::ExpandBuf* pReply)
45290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
4537934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  // static void WaitForSuspend(JDWP::ObjectId thread_id);
454caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes
455026b14660723c2b25a4f3ef6394f43a4fe64ba92Elliott Hughes  // Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
456caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes  // returns all threads.
457a06430c76981d545b5f2b64a7ef53c44c030cf73Sebastien Hertz  static void GetThreads(mirror::Object* thread_group, std::vector<JDWP::ObjectId>* thread_ids)
458bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
459caf7654a0e6c76c7489970b1a246fccf220f9982Elliott Hughes
460c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static JDWP::JdwpError GetThreadFrameCount(JDWP::ObjectId thread_id, size_t* result)
46190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_);
46200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                         size_t frame_count, JDWP::ExpandBuf* buf)
464bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
46500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
466bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static JDWP::ObjectId GetThreadSelfId() REQUIRES_SHARED(Locks::mutator_lock_);
467bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static JDWP::ObjectId GetThreadId(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_);
4686995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
46900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void SuspendVM()
47090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
471253fa555d9424a56c52879449eabe73d5c96cf61Sebastien Hertz  static void ResumeVM()
47290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
47388d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError SuspendThread(JDWP::ObjectId thread_id, bool request_suspension = true)
47490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_,
47590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::thread_suspend_count_lock_);
47600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
47788d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static void ResumeThread(JDWP::ObjectId thread_id)
47890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
479bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  static void SuspendSelf();
481872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
48200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
48300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                       JDWP::ObjectId* result)
48490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
485bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
4868009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz  static JDWP::JdwpError GetLocalValues(JDWP::Request* request, JDWP::ExpandBuf* pReply)
487bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
4888009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz  static JDWP::JdwpError SetLocalValues(JDWP::Request* request)
489bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
49152d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static JDWP::JdwpError Interrupt(JDWP::ObjectId thread_id)
49290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_);
493f9501700f51586cb6ba7cc0ffcb5a920bd64adf1Elliott Hughes
494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
495872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * Debugger notification
496872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
4976a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  enum EventFlag {
4988696433d1b3d8ba15288483b777edd888de69135Elliott Hughes    kBreakpoint     = 0x01,
499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    kSingleStep     = 0x02,
500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    kMethodEntry    = 0x04,
501872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes    kMethodExit     = 0x08,
502872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  };
503e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static void PostFieldAccessEvent(ArtMethod* m, int dex_pc, mirror::Object* this_object,
504c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                                   ArtField* f)
505bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
506e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static void PostFieldModificationEvent(ArtMethod* m, int dex_pc,
507c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                                         mirror::Object* this_object, ArtField* f,
5083f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                                         const JValue* field_value)
509bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
51014691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  static void PostException(mirror::Throwable* exception)
511bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
51200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
51362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void UpdateDebugger(Thread* thread, mirror::Object* this_object,
514e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                             ArtMethod* method, uint32_t new_dex_pc,
5158379b2256be5d2be4ad083a76e9f8ec403c4d405Sebastien Hertz                             int event_flags, const JValue* return_value)
516bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
51700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
518f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  // Indicates whether we need deoptimization for debugging.
519f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz  static bool RequiresDeoptimization();
520f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz
5214d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Records deoptimization request in the queue.
5224d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  static void RequestDeoptimization(const DeoptimizationRequest& req)
523bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
524138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
5254d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Manage deoptimization after updating JDWP events list. Suspends all threads, processes each
5264d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // request and finally resumes all threads.
527138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  static void ManageDeoptimization()
528bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
529138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
530138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Breakpoints.
5314d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  static void WatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
532bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
5334d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  static void UnwatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
534bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
535138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
536eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  /*
537eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi   * Forced interpreter checkers for single-step and continue support.
538eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi   */
539eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
540eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // Indicates whether we need to force the use of interpreter to invoke a method.
541eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // This allows to single-step or continue into the called method.
542e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForCalling(Thread* thread, ArtMethod* m)
543bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
544eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    if (!IsDebuggerActive()) {
545eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi      return false;
546eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    }
547eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    return IsForcedInterpreterNeededForCallingImpl(thread, m);
548eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  }
549eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
550eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // Indicates whether we need to force the use of interpreter entrypoint when calling a
551eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // method through the resolution trampoline. This allows to single-step or continue into
552eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // the called method.
553e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForResolution(Thread* thread, ArtMethod* m)
554bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
555eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    if (!IsDebuggerActive()) {
556eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi      return false;
557eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    }
558eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    return IsForcedInterpreterNeededForResolutionImpl(thread, m);
559eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  }
560eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
561eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // Indicates whether we need to force the use of instrumentation entrypoint when calling
562eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // a method through the resolution trampoline. This allows to deoptimize the stack for
563eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // debugging when we returned from the called method.
564e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInstrumentationNeededForResolution(Thread* thread, ArtMethod* m)
565bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
566eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    if (!IsDebuggerActive()) {
567eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi      return false;
568eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    }
569eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    return IsForcedInstrumentationNeededForResolutionImpl(thread, m);
570eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  }
571eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
572eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // Indicates whether we need to force the use of interpreter when returning from the
573eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // interpreter into the runtime. This allows to deoptimize the stack and continue
574eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // execution with interpreter for debugging.
575e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForUpcall(Thread* thread, ArtMethod* m)
576bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
57799170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang    if (!IsDebuggerActive() && !thread->HasDebuggerShadowFrames()) {
578eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi      return false;
579eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    }
580eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi    return IsForcedInterpreterNeededForUpcallImpl(thread, m);
581eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  }
582eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
583520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // Indicates whether we need to force the use of interpreter when handling an
584520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // exception. This allows to deoptimize the stack and continue execution with
585520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // the interpreter.
586520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // Note: the interpreter will start by handling the exception when executing
587520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // the deoptimized frames.
588520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  static bool IsForcedInterpreterNeededForException(Thread* thread)
589bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
59099170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang    if (!IsDebuggerActive() && !thread->HasDebuggerShadowFrames()) {
591520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz      return false;
592520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz    }
593520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz    return IsForcedInterpreterNeededForExceptionImpl(thread);
594520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  }
595520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz
596138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Single-stepping.
59788d630950cb5c6a1cb6457ce03a17c074ae13628Elliott Hughes  static JDWP::JdwpError ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize size,
59800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                       JDWP::JdwpStepDepth depth)
599bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
60061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz  static void UnconfigureStep(JDWP::ObjectId thread_id)
601bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
603cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  /*
604cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz   * Invoke support
605cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz   */
606cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
607cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Called by the JDWP thread to prepare invocation in the event thread (suspended on an event).
608cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // If the information sent by the debugger is incorrect, it will send a reply with the
609cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // appropriate error code. Otherwise, it will attach a DebugInvokeReq object to the event thread
610cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // and resume it (and possibly other threads depending on the invoke options).
611cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Unlike other commands, the JDWP thread will not send the reply to the debugger (see
612cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // JdwpState::ProcessRequest). The reply will be sent by the event thread itself after method
613cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // invocation completes (see FinishInvokeMethod). This is required to allow the JDWP thread to
614cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // process incoming commands from the debugger while the invocation is still in progress in the
615cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // event thread, especially if it gets suspended by a debug event occurring in another thread.
616cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  static JDWP::JdwpError PrepareInvokeMethod(uint32_t request_id, JDWP::ObjectId thread_id,
617cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                                             JDWP::ObjectId object_id, JDWP::RefTypeId class_id,
618cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                                             JDWP::MethodId method_id, uint32_t arg_count,
619cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                                             uint64_t arg_values[], JDWP::JdwpTag* arg_types,
620cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                                             uint32_t options)
62190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
622bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
623cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
624cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Called by the event thread to execute a method prepared by the JDWP thread in the given
625cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // DebugInvokeReq object. Once the invocation completes, the event thread attaches a reply
626cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // to that DebugInvokeReq object so it can be sent to the debugger only when the event thread
627cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // is ready to suspend (see FinishInvokeMethod).
628872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  static void ExecuteMethod(DebugInvokeReq* pReq);
629872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
630cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // Called by the event thread to send the reply of the invoke (created in ExecuteMethod)
631cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // before suspending itself. This is to ensure the thread is ready to suspend before the
632cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  // debugger receives the reply.
633cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  static void FinishInvokeMethod(DebugInvokeReq* pReq);
634cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
635872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes  /*
636872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   * DDM support.
637872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes   */
63800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendThreadNotification(Thread* t, uint32_t type)
639bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
64052d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static void DdmSetThreadNotification(bool enable)
64190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_);
642c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers  static bool DdmHandlePacket(JDWP::Request* request, uint8_t** pReplyBuf, int* pReplyLen);
643bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static void DdmConnected() REQUIRES_SHARED(Locks::mutator_lock_);
644bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static void DdmDisconnected() REQUIRES_SHARED(Locks::mutator_lock_);
64500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes)
646bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
64700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendChunk(uint32_t type, size_t len, const uint8_t* buf)
648bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
64900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count)
650bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
651767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes
652a6b1ead81603513fd40b77fd72f06d8cb1f35276Mathieu Chartier  // Visit breakpoint roots, used to prevent unloading of methods with breakpoints.
653bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier  static void VisitRoots(RootVisitor* visitor)
654bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
6553b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier
656545a064aca775ba801790fced3d713d8a87bfc61Elliott Hughes  /*
6578c2ff641294715864013737fdec57cdfd410270cMan Cao   * Allocation tracking support.
658545a064aca775ba801790fced3d713d8a87bfc61Elliott Hughes   */
65990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
66052d131d8e71ae9ea915ea84a3f95d49547e8e661Sebastien Hertz  static jbyteArray GetRecentAllocations()
661bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
66290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
663545a064aca775ba801790fced3d713d8a87bfc61Elliott Hughes
664767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  enum HpifWhen {
665767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPIF_WHEN_NEVER = 0,
666767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPIF_WHEN_NOW = 1,
667767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPIF_WHEN_NEXT_GC = 2,
668767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPIF_WHEN_EVERY_GC = 3
669767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  };
67000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static int DdmHandleHpifChunk(HpifWhen when)
671bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
672767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes
673767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  enum HpsgWhen {
674767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPSG_WHEN_NEVER = 0,
675767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPSG_WHEN_EVERY_GC = 1,
676767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  };
677767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  enum HpsgWhat {
678767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPSG_WHAT_MERGED_OBJECTS = 0,
679767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes    HPSG_WHAT_DISTINCT_OBJECTS = 1,
680767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  };
681767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes  static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
682767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes
68300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendHeapInfo(HpifWhen reason)
684bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
68500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void DdmSendHeapSegments(bool native)
686bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
687545a064aca775ba801790fced3d713d8a87bfc61Elliott Hughes
6886995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static ObjectRegistry* GetObjectRegistry() {
6896995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz    return gRegistry;
6906995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  }
6916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
6926995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o)
693bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
6946995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
6953398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier  static JDWP::JdwpTypeTag GetTypeTag(ObjPtr<mirror::Class> klass)
696bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
6976995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
698c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  static JDWP::FieldId ToFieldId(const ArtField* f)
699bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
7006995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
701e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static void SetJdwpLocation(JDWP::JdwpLocation* location, ArtMethod* m, uint32_t dex_pc)
702bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_)
70390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
7046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
705ad466adf38db74a9840659626858196091151a64Mathieu Chartier  static JDWP::JdwpState* GetJdwpState();
706ad466adf38db74a9840659626858196091151a64Mathieu Chartier
707bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static uint32_t GetInstrumentationEvents() REQUIRES_SHARED(Locks::mutator_lock_) {
7089d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz    return instrumentation_events_;
7099d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz  }
7109d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz
71104bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  static ThreadLifecycleCallback* GetThreadLifecycleCallback() {
71204bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe    return &thread_lifecycle_callback_;
71304bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  }
7140f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  static ClassLoadCallback* GetClassLoadCallback() {
7150f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe    return &class_load_callback_;
7160f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  }
71704bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe
718545a064aca775ba801790fced3d713d8a87bfc61Elliott Hughes private:
719cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  static void ExecuteMethodWithoutPendingException(ScopedObjectAccess& soa, DebugInvokeReq* pReq)
720bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
721cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
722cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz  static void BuildInvokeReply(JDWP::ExpandBuf* pReply, uint32_t request_id,
723cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                               JDWP::JdwpTag result_tag, uint64_t result_value,
724cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz                               JDWP::ObjectId exception)
725bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
726cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz
7278009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz  static JDWP::JdwpError GetLocalValue(const StackVisitor& visitor,
7288009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz                                       ScopedObjectAccessUnchecked& soa, int slot,
7298009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz                                       JDWP::JdwpTag tag, uint8_t* buf, size_t width)
730bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
73199170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  static JDWP::JdwpError SetLocalValue(Thread* thread, StackVisitor& visitor, int slot,
73299170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang                                       JDWP::JdwpTag tag, uint64_t value, size_t width)
733bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
7348009f39c6d63181a6cd0e348ce732997dbdf3d20Sebastien Hertz
735bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_);
73604bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe
73704bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  static void PostThreadStart(Thread* t)
73804bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
73904bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  static void PostThreadDeath(Thread* t)
74004bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
74100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static void PostThreadStartOrStop(Thread*, uint32_t)
742bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
743a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes
7440f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  static void PostClassPrepare(mirror::Class* c)
7450f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
7460f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe
747e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static void PostLocationEvent(ArtMethod* method, int pcOffset,
7488379b2256be5d2be4ad083a76e9f8ec403c4d405Sebastien Hertz                                mirror::Object* thisPtr, int eventFlags,
7498379b2256be5d2be4ad083a76e9f8ec403c4d405Sebastien Hertz                                const JValue* return_value)
750bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
7518379b2256be5d2be4ad083a76e9f8ec403c4d405Sebastien Hertz
7524d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  static void ProcessDeoptimizationRequest(const DeoptimizationRequest& request)
753aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_);
7544d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
7557ec2f1ca3cbd021848da75d5566f7239ce29676fSebastien Hertz  static void RequestDeoptimizationLocked(const DeoptimizationRequest& req)
756bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
7577ec2f1ca3cbd021848da75d5566f7239ce29676fSebastien Hertz
758e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForCallingImpl(Thread* thread, ArtMethod* m)
759bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
760eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
761e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForResolutionImpl(Thread* thread, ArtMethod* m)
762bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
763eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
764e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInstrumentationNeededForResolutionImpl(Thread* thread, ArtMethod* m)
765bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
766eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
767e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  static bool IsForcedInterpreterNeededForUpcallImpl(Thread* thread, ArtMethod* m)
768bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
769eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
770520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  static bool IsForcedInterpreterNeededForExceptionImpl(Thread* thread)
771bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
772520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz
773eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // Indicates whether the debugger is making requests.
774eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  static bool gDebuggerActive;
775eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi
7764e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  // Indicates whether we should drop the JDWP connection because the runtime stops or the
7774e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  // debugger called VirtualMachine.Dispose.
7784e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz  static bool gDisposed;
7794e5b20863898006ec6c9d120cda167d38dda6e60Sebastien Hertz
780eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi  // The registry mapping objects to JDWP ids.
7816995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz  static ObjectRegistry* gRegistry;
7826995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz
7834d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Deoptimization requests to be processed each time the event list is updated. This is used when
7844d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // registering and unregistering events so we do not deoptimize while holding the event list
7854d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // lock.
78642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // TODO rename to instrumentation_requests.
787306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static std::vector<DeoptimizationRequest> deoptimization_requests_ GUARDED_BY(Locks::deoptimization_lock_);
7884d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
7894d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Count the number of events requiring full deoptimization. When the counter is > 0, everything
7904d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // is deoptimized, otherwise everything is undeoptimized.
7914d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // Note: we fully deoptimize on the first event only (when the counter is set to 1). We fully
7924d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz  // undeoptimize when the last event is unregistered (when the counter is set to 0).
793306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t full_deoptimization_event_count_ GUARDED_BY(Locks::deoptimization_lock_);
7944d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz
79542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  static size_t* GetReferenceCounterForEvent(uint32_t instrumentation_event);
79642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
79742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // Instrumentation event reference counters.
79842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // TODO we could use an array instead of having all these dedicated counters. Instrumentation
79942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  // events are bits of a mask so we could convert them to array index.
800306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t dex_pc_change_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
801306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t method_enter_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
802306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t method_exit_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
803306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t field_read_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
804306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t field_write_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
805306db81aba41eb244a4e8299cf58ac18ae9999c7Brian Carlstrom  static size_t exception_catch_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
80642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz  static uint32_t instrumentation_events_ GUARDED_BY(Locks::mutator_lock_);
80742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz
80804bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  class DbgThreadLifecycleCallback : public ThreadLifecycleCallback {
80904bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe   public:
81004bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe    void ThreadStart(Thread* self) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
81104bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe    void ThreadDeath(Thread* self) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
81204bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  };
81304bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe
8140f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  class DbgClassLoadCallback : public ClassLoadCallback {
8150f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe   public:
8160f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe    void ClassLoad(Handle<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
8170f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe    void ClassPrepare(Handle<mirror::Class> temp_klass,
8180f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe                      Handle<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
8190f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  };
8200f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe
82104bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe  static DbgThreadLifecycleCallback thread_lifecycle_callback_;
8220f01b583c3952d0219696480654a0db8fac4b661Andreas Gampe  static DbgClassLoadCallback class_load_callback_;
82304bbb5be5b9c0f0b3a72116353d23ea63c8bc5e9Andreas Gampe
824719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  DISALLOW_COPY_AND_ASSIGN(Dbg);
825872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes};
826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
827872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#define CHUNK_TYPE(_name) \
8288218847294600bbfcdc041a46c2b579b6e70cf3bElliott Hughes    static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
829872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
830872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}  // namespace art
831872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes
832fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_DEBUGGER_H_
833