thread.h revision 250455229aa0cc07bbd18174efe510bd52631a99
18d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes/*
28d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
38d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
48d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * you may not use this file except in compliance with the License.
68d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * You may obtain a copy of the License at
78d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
88d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes *
108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * See the License for the specific language governing permissions and
148d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * limitations under the License.
158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */
160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_THREAD_H_
180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_THREAD_H_
190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
20b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <pthread.h>
21a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
2202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes#include <bitset>
23a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iosfwd>
24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <list>
258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <string>
26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <vector>
27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
281f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "dex_file.h"
29578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
3069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes#include "jni_internal.h"
31578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h"
32578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h"
34b765be0d656c3073402693aeaf64e95a0e49f218Brian Carlstrom#include "mem_map.h"
35578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "runtime_stats.h"
3768e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h"
38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "trace.h"
39bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h"
40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array;
4437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class;
451f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker;
46edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader;
47bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context;
48475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughesclass DebugInvokeReq;
49a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method;
508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor;
510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object;
52b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime;
5368e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughesclass StackIndirectReferenceTable;
5455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement;
551da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase;
5640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Thread;
5740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass ThreadList;
5840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Throwable;
591da522de18ac6e4c2913c3233529e9dd115059f8buzbee
6055df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray;
614417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray;
624417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray;
630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6485d1545e985ac689db4bad7849880e843707c862Elliott Hughesclass PACKED Thread {
650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
668daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /* thread priorities, from java.lang.Thread */
678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  enum Priority {
688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMinPriority = 1,
698daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kNormPriority = 5,
708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMaxPriority = 10,
718daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  };
72b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  enum State {
73499c5133d361e7c659fc38e5ccfeb1280a7996f5Elliott Hughes    // These correspond to JDWP states (but needn't share the same values).
74499c5133d361e7c659fc38e5ccfeb1280a7996f5Elliott Hughes    kTerminated   = 0,        // TS_ZOMBIE
75499c5133d361e7c659fc38e5ccfeb1280a7996f5Elliott Hughes    kRunnable     = 1,        // TS_RUNNING
763ce4b266a8e620ae4205922d828acc5976a99006Elliott Hughes    kTimedWaiting = 2,        // TS_WAIT in Object.wait() with a timeout
77499c5133d361e7c659fc38e5ccfeb1280a7996f5Elliott Hughes    kBlocked      = 3,        // TS_MONITOR on a monitor
78499c5133d361e7c659fc38e5ccfeb1280a7996f5Elliott Hughes    kWaiting      = 4,        // TS_WAIT in Object.wait()
7993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    // Non-JDWP states.
8093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kInitializing = 5,        // allocated, not yet running --- TODO: unnecessary?
8193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kStarting     = 6,        // native thread started, not yet ready to run managed code
8293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kNative       = 7,        // off in a JNI native method
8393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kVmWait       = 8,        // waiting on a VM resource
8493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kSuspended    = 9,        // suspended, usually by GC or debugger
85b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  };
86b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
87932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Space to throw a StackOverflowError in.
88aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  static const size_t kStackOverflowReservedBytes = 4 * KB;
89c143c55718342519db5398e41dda31422cf16c79buzbee
9072db0d77d6c476c71c5bbaa14a80ca77f23a47f3Brian Carlstrom  static const size_t kDefaultStackSize = 96 * KB;
9161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
929b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  class StackVisitor {
939b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao   public:
940cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    virtual ~StackVisitor() {}
95530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes    // Return 'true' if we should continue to visit more frames, 'false' to stop.
96530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes    virtual bool VisitFrame(const Frame& frame, uintptr_t pc) = 0;
979b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  };
989b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao
9961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread.
100d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  static void Create(Object* peer, size_t stack_size);
10161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
10261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread from the calling thread.
103dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon);
104b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
105caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  // Reset internal state of child thread after fork.
106caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitAfterFork();
107caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom
108b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static Thread* Current() {
109d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    void* thread = pthread_getspecific(Thread::pthread_key_self_);
110d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    return reinterpret_cast<Thread*>(thread);
1110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
1120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
113761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  static Thread* FromManagedThread(Object* thread_peer);
11401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static Thread* FromManagedThread(JNIEnv* env, jobject thread);
1158e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  static uint32_t LockOwnerFromThreadLock(Object* thread_lock);
1168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
117899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // When full == true, dumps the detailed thread state and the thread stack (used for SIGQUIT).
118899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // When full == false, dumps a one-line summary of thread state (used for operator<<).
119899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  void Dump(std::ostream& os, bool full = true) const;
120a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
1210cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  State GetState() const {
1220cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return state_;
1230cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1258d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  State SetState(State new_state);
126a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes  void SetStateWithoutSuspendCheck(State new_state);
1278d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
128038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  bool IsDaemon();
129761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes  bool IsSuspended();
130038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes
1318d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  void WaitUntilSuspended();
1320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
1335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool HoldsLock(Object*);
1345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
1368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
1378daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
1388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
1398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * numbers indicate higher priority.
1408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
1418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void SetNativePriority(int newPriority);
1428daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
1438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
1448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
1458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * This is useful when attaching a thread through JNI.
1468daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
1478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
1488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
1498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static int GetNativePriority();
1508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
1510cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool CanAccessDirectReferences() const {
152caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom#ifdef MOVING_GARBAGE_COLLECTOR
153a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    // TODO: when we have a moving collector, we'll need: return state_ == kRunnable;
154caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom#endif
155a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    return true;
1560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
1570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
158dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t GetThinLockId() const {
159dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    return thin_lock_id_;
160b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  }
161b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
162d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t GetTid() const {
163d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    return tid_;
164d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  }
165e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
166ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer.
167899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  String* GetThreadName() const;
168899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
169ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
170ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  // allocation, or locking.
171ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  void GetThreadName(std::string& name) const;
172ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
173899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // Sets the thread's name.
174899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  void SetThreadName(const char* name);
175fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
176d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* GetPeer() const {
1778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return peer_;
1788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
1798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
180a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes  Object* GetThreadGroup() const;
181a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes
1829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats* GetStats() {
1839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    return &stats_;
1849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
1859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
186d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  int GetSuspendCount() const {
187d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes    return suspend_count_;
188d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  }
1890cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
190d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  // Returns the current Method* and native PC (not dex PC) for this thread.
191d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes  Method* GetCurrentMethod(uintptr_t* pc = NULL, Method*** sp = NULL) const;
19233dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao
1930e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool IsExceptionPending() const {
194b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes    return exception_ != NULL;
1950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
1960e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
197e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* GetException() const {
1980cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
1990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    return exception_;
2000e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2010e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2020cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetException(Throwable* new_exception) {
2030cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
2040cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    CHECK(new_exception != NULL);
2050cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: CHECK(exception_ == NULL);
2060cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = new_exception;  // TODO
2070cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2080cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2090cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void ClearException() {
2100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = NULL;
211a09576416788b916095739e43a16917e7948f3a4Elliott Hughes  }
212a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
213bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Find catch block and perform long jump to appropriate exception handle
214ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void DeliverException();
215bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
216bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Context* GetLongJumpContext();
217bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
2181a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame GetTopOfStack() const {
2191a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return top_of_managed_stack_;
2201a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
2211a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
2221a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // TODO: this is here for testing, remove when we have exception unit tests
2231a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // that use the real stack
224bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStack(void* stack, uintptr_t pc) {
2250cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack));
226bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
2270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
229bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStackPC(uintptr_t pc) {
230bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
231bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
232bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
2335cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  // 'msg' may be NULL.
2345cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  void ThrowNewException(const char* exception_class_descriptor, const char* msg);
2355cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes
2365cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes  void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...)
237362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes      __attribute__((format(printf, 3, 4)));
238a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
2394a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes  void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap);
2404a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes
2412ced6a534157d5d963693346904389c19775d2daElliott Hughes  // OutOfMemoryError is special, because we need to pre-allocate an instance.
2422ced6a534157d5d963693346904389c19775d2daElliott Hughes  void ThrowOutOfMemoryError(const char* msg);
243418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes  void ThrowOutOfMemoryError(Class* c, size_t byte_count);
24479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
2451a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame FindExceptionHandler(void* throw_pc, void** handler_pc);
2461a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
2471a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void* FindExceptionHandlerInMethod(const Method* method,
2481a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     void* throw_pc,
2491a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     const DexFile& dex_file,
2501a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     ClassLinker* class_linker);
251c143c55718342519db5398e41dda31422cf16c79buzbee
252be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void Startup();
253038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  static void FinishStartup();
254c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  static void Shutdown();
255b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // JNI methods
25769f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* GetJniEnv() const {
258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return jni_env_;
259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
261408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Number of references allocated in SIRTs on this thread
262408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  size_t NumSirtReferences();
263a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
264408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Is the given obj in this thread's stack indirect reference table?
265408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  bool SirtContains(jobject obj);
266408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers
2678dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao  void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg);
2688dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao
269408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Convert a jobject into a Object*
270408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* DecodeJObject(jobject obj);
271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
2728daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.interrupted.
2738daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool Interrupted() {
27485d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
2758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    bool interrupted = interrupted_;
2768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    interrupted_ = false;
2778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted;
2788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
2798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
2818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool IsInterrupted() {
28285d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
2838daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted_;
2848daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
2858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Interrupt() {
28785d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
2885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (interrupted_) {
2895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
2905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
2915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    interrupted_ = true;
2925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
2935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
2945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Notify() {
29685d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
2975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
2985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
2995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3006de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // Linked list recording transitions from native to managed code
301b04f69f90d2594092bec5b294bbe7329d295bd66Ian Rogers  void PushNativeToManagedRecord(NativeToManagedRecord* record);
302b04f69f90d2594092bec5b294bbe7329d295bd66Ian Rogers  void PopNativeToManagedRecord(const NativeToManagedRecord& record);
3036de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
304bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* GetClassLoaderOverride() {
3050cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: need to place the class_loader_override_ in a handle
3060cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // DCHECK(CanAccessDirectReferences());
307c143c55718342519db5398e41dda31422cf16c79buzbee    return class_loader_override_;
308c143c55718342519db5398e41dda31422cf16c79buzbee  }
309c143c55718342519db5398e41dda31422cf16c79buzbee
310bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  void SetClassLoaderOverride(const ClassLoader* class_loader_override) {
311c143c55718342519db5398e41dda31422cf16c79buzbee    class_loader_override_ = class_loader_override;
312c143c55718342519db5398e41dda31422cf16c79buzbee  }
313c143c55718342519db5398e41dda31422cf16c79buzbee
314aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // Create the internal representation of a stack trace, that is more time
315aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // and space efficient to compute than the StackTraceElement[]
31601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  jobject CreateInternalStackTrace(JNIEnv* env) const;
31701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes
31801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
31901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many
32001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated
32101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // with the number of valid frames in the returned array.
32201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
32301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes      jobjectArray output_array = NULL, int* stack_depth = NULL);
32455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
325d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers  void VisitRoots(Heap::RootVisitor* visitor, void* arg);
326410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
327250455229aa0cc07bbd18174efe510bd52631a99jeffhao#if VERIFY_OBJECT_ENABLED
328250455229aa0cc07bbd18174efe510bd52631a99jeffhao  void VerifyStack();
329250455229aa0cc07bbd18174efe510bd52631a99jeffhao#else
330250455229aa0cc07bbd18174efe510bd52631a99jeffhao  void VerifyStack() {}
331250455229aa0cc07bbd18174efe510bd52631a99jeffhao#endif
332250455229aa0cc07bbd18174efe510bd52631a99jeffhao
333be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
334be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
335be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
336be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
337be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SelfOffset() {
338be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
339be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
340be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
341be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionOffset() {
342be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
343be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
344be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
34554e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  static ThreadOffset ThinLockIdOffset() {
346be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
347be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
348be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
349be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset CardTableOffset() {
350be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
351be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
352be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
353be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SuspendCountOffset() {
354be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_));
355be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
356be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
357be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset StateOffset() {
35893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_));
359be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
360be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
361932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of stack less any space reserved for stack overflow
362932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  size_t GetStackSize() {
36330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    return stack_size_ - (stack_end_ - stack_begin_);
364932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
365932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
366932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during a stack overflow
367932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void SetStackEndForStackOverflow() {
368932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // During stack overflow we allow use of the full stack
36930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    if (stack_end_ == stack_begin_) {
3703b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes      DumpStack(std::cerr);
3713b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes      LOG(FATAL) << "Need to increase kStackOverflowReservedBytes (currently "
3723b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes                 << kStackOverflowReservedBytes << ")";
3733b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes    }
3743b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes
37530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    stack_end_ = stack_begin_;
376932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
377932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
378932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during regular execution
379932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void ResetDefaultStackEnd() {
380932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
381932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // to throw a StackOverflowError.
38230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers    stack_end_ = stack_begin_ + kStackOverflowReservedBytes;
383932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
384932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
385449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  static ThreadOffset StackEndOffset() {
386449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
387be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
388be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
389be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset JniEnvOffset() {
390be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
391be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
392be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
393be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
394be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) +
395be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes        OFFSETOF_MEMBER(Frame, sp_));
396be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
397be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
398bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  static ThreadOffset TopOfManagedStackPcOffset() {
399bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_));
400bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
401bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
40240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  void PushSirt(StackIndirectReferenceTable* sirt);
40340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom  StackIndirectReferenceTable* PopSirt();
40440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom
405be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopSirtOffset() {
406be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
407be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
408be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
409530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes  void WalkStack(StackVisitor* visitor, bool include_upcalls = false) const;
4109407c60800c95902fba0b3c3265520d47c1e7052Shih-wei Liao
411475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* GetInvokeReq() {
412475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes    return debug_invoke_req_;
413475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  }
414475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
415e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  bool IsTraceStackEmpty() const {
416e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    return trace_stack_->empty();
417e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
418e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
419a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  TraceStackFrame GetTraceStackFrame(uint32_t depth) const {
420a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao    return trace_stack_->at(trace_stack_->size() - depth - 1);
421a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  }
422a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
423e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  void PushTraceStackFrame(const TraceStackFrame& frame) {
424e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    trace_stack_->push_back(frame);
425e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
426e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
427e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  TraceStackFrame PopTraceStackFrame() {
428e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    TraceStackFrame frame = trace_stack_->back();
429e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    trace_stack_->pop_back();
430e343b76af81a005ef64f5e75a555389fd9147dabjeffhao    return frame;
431e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
432e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
433a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes  void CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking);
434a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes  void CheckSafeToWait(MutexRank rank);
435ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
4360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
437dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  Thread();
438c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  ~Thread();
43902b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes  friend class ThreadList;  // For ~Thread.
4400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4415fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void CreatePeer(const char* name, bool as_daemon);
4425fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  friend class Runtime; // For CreatePeer.
4435fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
444d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpState(std::ostream& os) const;
445d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpStack(std::ostream& os) const;
446ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  void DumpNativeStack(std::ostream& os) const;
447d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
448accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  // Out-of-line conveniences for debugging in gdb.
449498508c1187dc07d3eae5476784cde20f5224d93Elliott Hughes  static Thread* CurrentFromGdb(); // Like Thread::Current.
450accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  void DumpFromGdb() const; // Like Thread::Dump(std::cerr).
451accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
45293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  void Attach(const Runtime* runtime);
45393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  static void* CreateCallback(void* arg);
45493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
455accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes  void HandleUncaughtExceptions();
4564514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom  void RemoveFromThreadGroup();
457accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes
4585d76c435082332ef79a22962386fa92a0870e378Ian Rogers  void InitCardTable();
459b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void InitCpu();
4603ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee  void InitFunctionPointers();
461caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitTid();
462caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom  void InitPthreadKeySelf();
463be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  void InitStackHwm();
464be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
4655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void NotifyLocked() {
4665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (wait_monitor_ != NULL) {
46785d1545e985ac689db4bad7849880e843707c862Elliott Hughes      wait_cond_->Signal();
4685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
4695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void ThreadExitCallback(void* arg);
472b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
473dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Thin lock thread id. This is a small integer used by the thin lock implementation.
474dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // This is not to be confused with the native thread's tid, nor is it the value returned
475dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
476dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // important difference between this id and the ids visible to managed code is that these
477dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // ones get reused (to ensure that they fit in the number of bits available).
478dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t thin_lock_id_;
479b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
480d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // System thread id.
481d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t tid_;
482d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
483dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Our managed peer (an instance of java.lang.Thread).
484d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* peer_;
4858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
4868e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // The top_of_managed_stack_ and top_of_managed_stack_pc_ fields are accessed from
4878e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // compiled code, so we keep them early in the structure to (a) avoid having to keep
4888e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // fixing the assembler offsets and (b) improve the chances that these will still be aligned.
4898e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
4908e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // Top of the managed stack, written out prior to the state transition from
49168e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes  // kRunnable to kNative. Uses include giving the starting point for scanning
4928e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // a managed stack when a thread is in native code.
4938e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Frame top_of_managed_stack_;
4948e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // PC corresponding to the call out of the top_of_managed_stack_ frame
4958e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uintptr_t top_of_managed_stack_pc_;
4968e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
4978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Guards the 'interrupted_' and 'wait_monitor_' members.
49885d1545e985ac689db4bad7849880e843707c862Elliott Hughes  mutable Mutex* wait_mutex_;
49985d1545e985ac689db4bad7849880e843707c862Elliott Hughes  ConditionVariable* wait_cond_;
5008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Pointer to the monitor lock we're currently waiting on (or NULL), guarded by wait_mutex_.
5018daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  Monitor* wait_monitor_;
5028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Thread "interrupted" status; stays raised until queried or thrown, guarded by wait_mutex_.
5038e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uint32_t interrupted_;
5045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // The next thread in the wait set this thread is part of.
5055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* wait_next_;
5068e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // If we're blocked in MonitorEnter, this is the object we're trying to lock.
5078e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Object* monitor_enter_object_;
5085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  friend class Monitor;
510dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
5119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats stats_;
5129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
5135d76c435082332ef79a22962386fa92a0870e378Ian Rogers  // The biased card table, see CardTable for details
5145d76c435082332ef79a22962386fa92a0870e378Ian Rogers  byte* card_table_;
515c143c55718342519db5398e41dda31422cf16c79buzbee
516449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
517449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // We leave extra space so there's room for the code that throws StackOverflowError.
518449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  byte* stack_end_;
519be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
520932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of the stack
521932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  size_t stack_size_;
522932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
523932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // The "lowest addressable byte" of the stack
52430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers  byte* stack_begin_;
525932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
5266de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // A linked list (of stack allocated records) recording transitions from
5276de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // native to managed code.
5286de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  NativeToManagedRecord* native_to_managed_record_;
5296de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
530408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Top of linked list of stack indirect reference tables or NULL for none
531408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* top_sirt_;
532b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
533b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Every thread may have an associated JNI environment
53469f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* jni_env_;
535b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
53693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  volatile State state_;
537b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
53869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // Initialized to "this". On certain architectures (such as x86) reading
53969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // off of Thread::Current is easy but getting the address of Thread::Current
54069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // is hard. This field can be read off of Thread::Current to give the address.
54169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Thread* self_;
54269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
54369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Runtime* runtime_;
54469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
54569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // The pending exception or NULL.
546e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* exception_;
5470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
54845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // A non-zero value is used to tell the current thread to enter a safe point
54945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // at the next poll.
55045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  int suspend_count_;
551234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  // How much of 'suspend_count_' is by request of the debugger, used to set things right
552234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  // when the debugger detaches. Must be <= suspend_count_.
553234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes  int debug_suspend_count_;
55445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
555edcc09c737b00462881f147602656739d029571eElliott Hughes  // Needed to get the right ClassLoader in JNI_OnLoad, but also
556edcc09c737b00462881f147602656739d029571eElliott Hughes  // useful for testing.
557bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* class_loader_override_;
558c143c55718342519db5398e41dda31422cf16c79buzbee
559bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
56085d1545e985ac689db4bad7849880e843707c862Elliott Hughes  Context* long_jump_context_;
561bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
562418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes  // A boolean telling us whether we're recursively throwing OOME.
563726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  uint32_t throwing_OutOfMemoryError_;
564726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes
565726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes  Throwable* pre_allocated_OutOfMemoryError_;
566418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes
567475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  // JDWP invoke-during-breakpoint support.
568475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes  DebugInvokeReq* debug_invoke_req_;
569475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes
57069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // TLS key used to retrieve the VM thread object.
571b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static pthread_key_t pthread_key_self_;
572b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
573e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Additional stack used by method tracer to store method and return pc values.
574e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Stored as a pointer since std::vector is not PACKED.
575e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  std::vector<TraceStackFrame>* trace_stack_;
576e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
577899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  // A cached copy of the java.lang.Thread's name.
578899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes  std::string* name_;
579899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes
580ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes  uint32_t held_mutexes_[kMaxMutexRank + 1];
581ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes
582a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers public:
583a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  // Runtime support function pointers
584a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pDebugMe)(Method*, uint32_t);
585a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pMemcpy)(void*, const void*, size_t);
586a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  uint64_t (*pShlLong)(uint64_t, uint32_t);
587a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  uint64_t (*pShrLong)(uint64_t, uint32_t);
588a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  uint64_t (*pUshrLong)(uint64_t, uint32_t);
589a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pI2f)(int);
590a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pF2iz)(float);
591a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pD2f)(double);
592a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pF2d)(float);
593a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pI2d)(int);
594a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pD2iz)(double);
595c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  float (*pL2f)(int64_t);
596c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  double (*pL2d)(int64_t);
597c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pF2l)(float);
598c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pD2l)(double);
599a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pFadd)(float, float);
600a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pFsub)(float, float);
601a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pFdiv)(float, float);
602a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pFmul)(float, float);
603a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  float (*pFmodf)(float, float);
604a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pDadd)(double, double);
605a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pDsub)(double, double);
606a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pDdiv)(double, double);
607a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pDmul)(double, double);
608a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  double (*pFmod)(double, double);
609a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pIdivmod)(int, int);
610a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pIdiv)(int, int);
611c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLadd)(int64_t, int64_t);
612c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLsub)(int64_t, int64_t);
613c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLand)(int64_t, int64_t);
614c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLor)(int64_t, int64_t);
615c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLxor)(int64_t, int64_t);
616c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLmul)(int64_t, int64_t);
617c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers  int64_t (*pLdivmod)(int64_t, int64_t);
618a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pCheckSuspendFromCode)(Thread*);  // Stub that is called when the suspend count is non-zero
619a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pTestSuspendFromCode)();  // Stub that is periodically called to test the suspend count
620a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pAllocObjectFromCode)(uint32_t, void*);
621a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pAllocObjectFromCodeWithAccessCheck)(uint32_t, void*);
622a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pAllocArrayFromCode)(uint32_t, void*, int32_t);
623a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
624a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pCanPutArrayElementFromCode)(void*, void*);
625a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t);
626a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pCheckAndAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
627a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pCheckCastFromCode)(void*, void*);
628a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj);
629a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pDeliverException)(void*);
630a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);
631a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pFindNativeMethod)(Thread* thread);
632a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int32_t (*pGet32Instance)(uint32_t, void*);
633a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int64_t (*pGet64Instance)(uint32_t, void*);
634a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pGetObjInstance)(uint32_t, void*);
635a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int32_t (*pGet32Static)(uint32_t);
636a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int64_t (*pGet64Static)(uint32_t);
637a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pGetObjStatic)(uint32_t);
638a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pHandleFillArrayDataFromCode)(void*, void*);
639a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pInitializeStaticStorage)(uint32_t, void*);
640a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  uint32_t (*pInstanceofNonTrivialFromCode)(const Class*, const Class*);
641c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void (*pInvokeDirectTrampolineWithAccessCheck)(uint32_t, void*);
642a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pInvokeInterfaceTrampoline)(uint32_t, void*);
643a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pInvokeInterfaceTrampolineWithAccessCheck)(uint32_t, void*);
644c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers  void (*pInvokeStaticTrampolineWithAccessCheck)(uint32_t, void*);
645a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pInvokeSuperTrampolineWithAccessCheck)(uint32_t, void*);
646a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pInvokeVirtualTrampolineWithAccessCheck)(uint32_t, void*);
647a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pInitializeTypeFromCode)(uint32_t, void*);
648a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pInitializeTypeAndVerifyAccessFromCode)(uint32_t, void*);
649a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pLockObjectFromCode)(void*);
650a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void* (*pResolveStringFromCode)(void*, uint32_t);
651a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSet32Instance)(uint32_t, void*, int32_t);  // field_idx, obj, src
652a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSet64Instance)(uint32_t, void*, int64_t);
653a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSetObjInstance)(uint32_t, void*, void*);
654a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSet32Static)(uint32_t, int32_t);
655a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSet64Static)(uint32_t, int64_t);
656a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  int (*pSetObjStatic)(uint32_t, void*);
657a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowStackOverflowFromCode)(void*);
658a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowNullPointerFromCode)();
659a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
660a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowDivZeroFromCode)();
661a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowVerificationErrorFromCode)(int32_t, int32_t);
662a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowNegArraySizeFromCode)(int32_t);
663a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowNoSuchMethodFromCode)(int32_t);
664a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp);
665a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pUnlockObjectFromCode)(void*);
6661984651929744dd603fd082e23eacd877b9bc177Ian Rogers  const void* (*pUnresolvedDirectMethodTrampolineFromCode)(Method*, Method**, Thread*,
6671984651929744dd603fd082e23eacd877b9bc177Ian Rogers                                                           Runtime::TrampolineType);
668a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers  void (*pUpdateDebuggerFromCode)(void*, void*, int32_t, void*);
66911f9d2130e938511efceb6d2a4793cee7dfdde35Bill Buzbee  bool (*pCmplFloat)(float, float);
67011f9d2130e938511efceb6d2a4793cee7dfdde35Bill Buzbee  bool (*pCmpgFloat)(float, float);
67111f9d2130e938511efceb6d2a4793cee7dfdde35Bill Buzbee  bool (*pCmplDouble)(double, double);
67211f9d2130e938511efceb6d2a4793cee7dfdde35Bill Buzbee  bool (*pCmpgDouble)(double, double);
673a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
674a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers private:
6750e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Thread);
6760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
677bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
678330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread);
679b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state);
6800e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
681ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange {
682ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public:
683ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) {
684ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    old_thread_state_ = thread_->SetState(new_state);
685ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
686ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
687ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ~ScopedThreadStateChange() {
688ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    thread_->SetState(old_thread_state_);
689ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
690ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
691ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private:
692ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread* thread_;
693ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread::State old_thread_state_;
694ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange);
695ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes};
696ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
6970e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
6980e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_THREAD_H_
700