thread.h revision 5f79133a435ebcb20000370d56046fe01201dd80
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>
26b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
271f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "dex_file.h"
28578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
2969f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes#include "jni_internal.h"
30578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h"
31578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h"
328daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "mutex.h"
33b765be0d656c3073402693aeaf64e95a0e49f218Brian Carlstrom#include "mem_map.h"
34578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
35bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h"
36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3969f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array;
4037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class;
411f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker;
42edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader;
43bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context;
44a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method;
458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor;
460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object;
47b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime;
480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread;
49b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList;
50e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughesclass Throwable;
5155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement;
521da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase;
531da522de18ac6e4c2913c3233529e9dd115059f8buzbee
5455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray;
554417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray;
564417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray;
570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
58408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// Stack allocated indirect reference table, allocated within the bridge frame
59408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// between managed and native code.
60408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogersclass StackIndirectReferenceTable {
61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public:
62408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Number of references contained within this SIRT
63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  size_t NumberOfReferences() {
64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return number_of_references_;
65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
67408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Link to previous SIRT or NULL
68408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* Link() {
69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return link_;
70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
72408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object** References() {
73408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return references_;
74a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers  }
75a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
76408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Offset of length within SIRT, used by generated code
77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  static size_t NumberOfReferencesOffset() {
78408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_);
79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
81408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Offset of link within SIRT, used by generated code
82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  static size_t LinkOffset() {
83408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_);
84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private:
87408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable() {}
88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  size_t number_of_references_;
90408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* link_;
91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
92a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers  // Fake array, really allocated and filled in by jni_compiler.
93408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* references_[0];
94a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
95408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable);
96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
986de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogersstruct NativeToManagedRecord {
99bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  NativeToManagedRecord* link_;
100bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void* last_top_of_managed_stack_;
101bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t last_top_of_managed_stack_pc_;
1026de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers};
1036de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
1041a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao// Iterator over managed frames up to the first native-to-managed transition
1051a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liaoclass Frame {
1069b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public:
1071a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame() : sp_(NULL) {}
1081a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1090cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method* GetMethod() const {
110a09576416788b916095739e43a16917e7948f3a4Elliott Hughes    return (sp_ != NULL) ? *sp_ : NULL;
1111a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1121a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1131a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  bool HasNext() const {
1141a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return NextMethod() != NULL;
1151a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1161a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1171a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void Next();
1181a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
119bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t GetReturnPC() const;
120bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
121bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t LoadCalleeSave(int num) const;
1221a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1230cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method** GetSP() const {
1241a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return sp_;
1251a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1261a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1271a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // TODO: this is here for testing, remove when we have exception unit tests
1281a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // that use the real stack
1290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetSP(Method** sp) {
1301a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    sp_ = sp;
1311a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1321a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1331a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao private:
1340cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method* NextMethod() const;
1351a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1361a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  friend class Thread;
1371a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1380cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method** sp_;
1391a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao};
1401a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread {
1420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
1438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /* thread priorities, from java.lang.Thread */
1448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  enum Priority {
1458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMinPriority = 1,
1468daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kNormPriority = 5,
1478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMaxPriority = 10,
1488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  };
149b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  enum State {
150b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro    kUnknown = -1,
15193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
15293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    // These match up with JDWP values.
15393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kTerminated   = 0,        // TERMINATED
15493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kRunnable     = 1,        // RUNNABLE or running now
15593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kTimedWaiting = 2,        // TIMED_WAITING in Object.wait()
15693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kBlocked      = 3,        // BLOCKED on a monitor
15793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kWaiting      = 4,        // WAITING in Object.wait()
15893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    // Non-JDWP states.
15993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kInitializing = 5,        // allocated, not yet running --- TODO: unnecessary?
16093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kStarting     = 6,        // native thread started, not yet ready to run managed code
16193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kNative       = 7,        // off in a JNI native method
16293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kVmWait       = 8,        // waiting on a VM resource
16393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kSuspended    = 9,        // suspended, usually by GC or debugger
164b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  };
165b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
166cefd1878e09fb0fb519a175545a99eb8c4a375b2buzbee  static const size_t kStackOverflowReservedBytes = 1024; // Space to throw a StackOverflowError in.
167c143c55718342519db5398e41dda31422cf16c79buzbee
16861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  static const size_t kDefaultStackSize = 64 * KB;
16961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
170c143c55718342519db5398e41dda31422cf16c79buzbee  // Runtime support function pointers
1714a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee  void (*pDebugMe)(Method*, uint32_t);
172c143c55718342519db5398e41dda31422cf16c79buzbee  void* (*pMemcpy)(void*, const void*, size_t);
1735433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pShlLong)(uint64_t, uint32_t);
1745433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pShrLong)(uint64_t, uint32_t);
1755433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pUshrLong)(uint64_t, uint32_t);
176c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pI2f)(int);
177c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pF2iz)(float);
178c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pD2f)(double);
179c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pF2d)(float);
180c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pI2d)(int);
181c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pD2iz)(double);
182c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pL2f)(long);
183c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pL2d)(long);
1841b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  long long (*pF2l)(float);
1851b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  long long (*pD2l)(double);
186c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFadd)(float, float);
187c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFsub)(float, float);
188c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFdiv)(float, float);
189c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFmul)(float, float);
190c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFmodf)(float, float);
191c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDadd)(double, double);
192c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDsub)(double, double);
193c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDdiv)(double, double);
194c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDmul)(double, double);
195c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pFmod)(double, double);
196c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pIdivmod)(int, int);
197c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pIdiv)(int, int);
198439c4fa0db980fb19e4a585723a64a3461e4c278buzbee  long long (*pLmul)(long long, long long);
199c143c55718342519db5398e41dda31422cf16c79buzbee  long long (*pLdivmod)(long long, long long);
200dfd3d70e58c37b5d56eded3a4469082d8bb26ee0buzbee  Array* (*pAllocFromCode)(uint32_t, Method*, int32_t);
2011da522de18ac6e4c2913c3233529e9dd115059f8buzbee  Array* (*pCheckAndAllocFromCode)(uint32_t, Method*, int32_t);
2021f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom  Object* (*pAllocObjectFromCode)(uint32_t, Method*);
203e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  uint32_t (*pGet32Static)(uint32_t, const Method*);
204e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSet32Static)(uint32_t, const Method*, uint32_t);
205e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  uint64_t (*pGet64Static)(uint32_t, const Method*);
206e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSet64Static)(uint32_t, const Method*, uint64_t);
207e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  Object* (*pGetObjStatic)(uint32_t, const Method*);
208e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSetObjStatic)(uint32_t, const Method*, Object*);
2090f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes  void (*pCanPutArrayElementFromCode)(const Class*, const Class*);
2102a475e7b93d754e0a7525bb5c7059386307ea63abuzbee  bool (*pInstanceofNonTrivialFromCode) (const Object*, const Class*);
2112a475e7b93d754e0a7525bb5c7059386307ea63abuzbee  void (*pCheckCastFromCode) (const Class*, const Class*);
2121b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);
2132a475e7b93d754e0a7525bb5c7059386307ea63abuzbee  void (*pUnlockObjectFromCode)(Thread*, Object*);
2141b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  void (*pLockObjectFromCode)(Thread*, Object*);
215bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void (*pThrowException)(void*);
2161b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  void (*pHandleFillArrayDataFromCode)(Array*, const uint16_t*);
2171b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  Class* (*pInitializeTypeFromCode)(uint32_t, Method*);
218561227c80077bbb4147f778043f1a836af6b9248buzbee  void (*pResolveMethodFromCode)(Method*, uint32_t);
2194a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee  void (*pInvokeInterfaceTrampoline)(void*, void*, void*, void*);
2201da522de18ac6e4c2913c3233529e9dd115059f8buzbee  StaticStorageBase* (*pInitializeStaticStorage)(uint32_t, const Method*);
22134cd9e58431504c36d0cb2a8fd0f3fac16dcb406buzbee  Field* (*pFindFieldFromCode)(uint32_t, const Method*);
2220d966cff87464544a264efdbfba6c379474d5928buzbee  void (*pCheckSuspendFromCode)(Thread*);
223cefd1878e09fb0fb519a175545a99eb8c4a375b2buzbee  void (*pStackOverflowFromCode)(Method*);
2245ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNullPointerFromCode)();
2255ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
2265ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowDivZeroFromCode)();
2275ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowVerificationErrorFromCode)(int32_t, int32_t);
2285ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNegArraySizeFromCode)(int32_t);
2295ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowRuntimeExceptionFromCode)(int32_t);
2305ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowInternalErrorFromCode)(int32_t);
2315ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNoSuchMethodFromCode)(int32_t);
232bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread);
233161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  void* (*pFindNativeMethod)(Thread* thread);
234161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj);
235c143c55718342519db5398e41dda31422cf16c79buzbee
2369b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  class StackVisitor {
2379b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao   public:
2380cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    virtual ~StackVisitor() {}
239bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    virtual void VisitFrame(const Frame& frame, uintptr_t pc) = 0;
2409b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  };
2419b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao
24261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread.
243d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  static void Create(Object* peer, size_t stack_size);
24461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
24561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread from the calling thread.
246dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon);
247b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
248b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static Thread* Current() {
249d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    void* thread = pthread_getspecific(Thread::pthread_key_self_);
250d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    return reinterpret_cast<Thread*>(thread);
2510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
2538daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static Thread* FromManagedThread(JNIEnv* env, jobject thread) {
2548daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    // TODO: make these more generally available, and cached.
2558daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    jclass java_lang_Thread = env->FindClass("java/lang/Thread");
2568daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    jfieldID fid = env->GetFieldID(java_lang_Thread, "vmData", "I");
2578daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return reinterpret_cast<Thread*>(static_cast<uintptr_t>(env->GetIntField(thread, fid)));
2588daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
2598daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
260a09576416788b916095739e43a16917e7948f3a4Elliott Hughes  void Dump(std::ostream& os) const;
261a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
2620cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  State GetState() const {
2630cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return state_;
2640cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2650cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2668d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  State SetState(State new_state);
2678d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
2688d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  void WaitUntilSuspended();
2690cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool HoldsLock(Object*);
2715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2728daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2738daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
2748daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
2768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * numbers indicate higher priority.
2778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void SetNativePriority(int newPriority);
2798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
2828daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * This is useful when attaching a thread through JNI.
2838daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2848daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
2858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2868daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static int GetNativePriority();
2878daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2880cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool CanAccessDirectReferences() const {
289a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    // TODO: when we have a moving collector, we'll need: return state_ == kRunnable;
290a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    return true;
2910cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2920cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
293dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t GetThinLockId() const {
294dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    return thin_lock_id_;
295b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  }
296b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
297d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t GetTid() const {
298d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    return tid_;
299d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  }
300e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
301e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  pthread_t GetImpl() const {
302be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return pthread_;
3030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3040e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
305d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* GetPeer() const {
3068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return peer_;
3078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
3088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3090cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // Returns the Method* for the current method.
3100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // This is used by the JNI implementation for logging and diagnostic purposes.
3110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  const Method* GetCurrentMethod() const {
3120cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return top_of_managed_stack_.GetMethod();
3130cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
3140cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool IsExceptionPending() const {
316b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes    return exception_ != NULL;
3170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
319e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* GetException() const {
3200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
3210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    return exception_;
3220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetException(Throwable* new_exception) {
3250cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
3260cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    CHECK(new_exception != NULL);
3270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: CHECK(exception_ == NULL);
3280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = new_exception;  // TODO
3290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
3300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void ClearException() {
3320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = NULL;
333a09576416788b916095739e43a16917e7948f3a4Elliott Hughes  }
334a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
335bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Find catch block and perform long jump to appropriate exception handle
336bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void DeliverException(Throwable* exception);
337bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
338bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Context* GetLongJumpContext();
339bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
3401a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame GetTopOfStack() const {
3411a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return top_of_managed_stack_;
3421a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
3431a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
3441a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // TODO: this is here for testing, remove when we have exception unit tests
3451a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // that use the real stack
346bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStack(void* stack, uintptr_t pc) {
3470cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack));
348bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
3490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
351bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStackPC(uintptr_t pc) {
352bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
353bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
354bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
355bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Returns a special method that describes all callee saves being spilt to the
356bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // stack.
357bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Method* CalleeSaveMethod() const;
358bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
359e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  void ThrowNewException(const char* exception_class_descriptor, const char* fmt, ...)
360a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes      __attribute__ ((format(printf, 3, 4)));
361a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
36279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // This exception is special, because we need to pre-allocate an instance.
36379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  void ThrowOutOfMemoryError();
36479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3651a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame FindExceptionHandler(void* throw_pc, void** handler_pc);
3661a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
3671a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void* FindExceptionHandlerInMethod(const Method* method,
3681a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     void* throw_pc,
3691a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     const DexFile& dex_file,
3701a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     ClassLinker* class_linker);
371c143c55718342519db5398e41dda31422cf16c79buzbee
372b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  void SetName(const char* name);
373b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
374be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void Startup();
375c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  static void Shutdown();
376b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
377b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // JNI methods
37869f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* GetJniEnv() const {
379b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return jni_env_;
380b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
381b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
382408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Number of references allocated in SIRTs on this thread
383408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  size_t NumSirtReferences();
384a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
385408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Is the given obj in this thread's stack indirect reference table?
386408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  bool SirtContains(jobject obj);
387408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers
388408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Convert a jobject into a Object*
389408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* DecodeJObject(jobject obj);
390b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
3918daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.interrupted.
3928daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool Interrupted() {
3938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    MutexLock mu(wait_mutex_);
3948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    bool interrupted = interrupted_;
3958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    interrupted_ = false;
3968daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted;
3978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
3988daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
4008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool IsInterrupted() {
4018daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    MutexLock mu(wait_mutex_);
4028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted_;
4038daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
4048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
4055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Interrupt() {
4065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    MutexLock mu(wait_mutex_);
4075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (interrupted_) {
4085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
4095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
4105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    interrupted_ = true;
4115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
4125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Notify() {
4155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    MutexLock mu(wait_mutex_);
4165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
4175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
41945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void RegisterExceptionEntryPoint(void (*handler)(Method**)) {
42045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers    exception_entry_point_ = handler;
42145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  }
42245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
42345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void RegisterSuspendCountEntryPoint(void (*handler)(Method**)) {
42445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers    suspend_count_entry_point_ = handler;
42545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  }
42645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
4276de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // Linked list recording transitions from native to managed code
4286de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  void PushNativeToManagedRecord(NativeToManagedRecord* record) {
429bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    record->last_top_of_managed_stack_ = reinterpret_cast<void*>(top_of_managed_stack_.GetSP());
430bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    record->last_top_of_managed_stack_pc_ = top_of_managed_stack_pc_;
431bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    record->link_ = native_to_managed_record_;
4326de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers    native_to_managed_record_ = record;
4331a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    top_of_managed_stack_.SetSP(NULL);
4346de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  }
4356de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  void PopNativeToManagedRecord(const NativeToManagedRecord& record) {
436bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    native_to_managed_record_ = record.link_;
437bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(record.last_top_of_managed_stack_));
438bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = record.last_top_of_managed_stack_pc_;
4396de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  }
4406de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
441bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* GetClassLoaderOverride() {
4420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: need to place the class_loader_override_ in a handle
4430cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // DCHECK(CanAccessDirectReferences());
444c143c55718342519db5398e41dda31422cf16c79buzbee    return class_loader_override_;
445c143c55718342519db5398e41dda31422cf16c79buzbee  }
446c143c55718342519db5398e41dda31422cf16c79buzbee
447bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  void SetClassLoaderOverride(const ClassLoader* class_loader_override) {
448c143c55718342519db5398e41dda31422cf16c79buzbee    class_loader_override_ = class_loader_override;
449c143c55718342519db5398e41dda31422cf16c79buzbee  }
450c143c55718342519db5398e41dda31422cf16c79buzbee
451aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // Create the internal representation of a stack trace, that is more time
452aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // and space efficient to compute than the StackTraceElement[]
453aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  jobject CreateInternalStackTrace() const;
454aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers
455aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  // Convert an internal stack trace representation to a StackTraceElement[]
456aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  static jobjectArray
457aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers      InternalStackTraceToStackTraceElementArray(jobject internal, JNIEnv* env);
45855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
459410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
460410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
461be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
462be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
463be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
464be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
465be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SelfOffset() {
466be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
467be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
468be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
469be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionOffset() {
470be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
472be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
473be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset IdOffset() {
474be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
475be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
476be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
477be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset CardTableOffset() {
478be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
479be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
480be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
481be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SuspendCountOffset() {
482be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_));
483be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
484be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
485be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset StateOffset() {
48693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_));
487be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
488be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
489449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  static ThreadOffset StackEndOffset() {
490449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
491be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
492be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
493be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset JniEnvOffset() {
494be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
495be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
496be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
497be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
498be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) +
499be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes        OFFSETOF_MEMBER(Frame, sp_));
500be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
501be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
502bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  static ThreadOffset TopOfManagedStackPcOffset() {
503bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_));
504bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
505bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
506be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopSirtOffset() {
507be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
508be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
509be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
510be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionEntryPointOffset() {
511be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_entry_point_));
512be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
513be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
514be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SuspendCountEntryPointOffset() {
515be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_entry_point_));
516be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
517be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
5180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
519dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  Thread();
520c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  ~Thread();
52102b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes  friend class ThreadList;  // For ~Thread.
5220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
5235fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void CreatePeer(const char* name, bool as_daemon);
5245fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  friend class Runtime; // For CreatePeer.
5255fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
526d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpState(std::ostream& os) const;
527d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpStack(std::ostream& os) const;
528d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
52993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  void Attach(const Runtime* runtime);
53093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  static void* CreateCallback(void* arg);
53193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
532b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void InitCpu();
5333ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee  void InitFunctionPointers();
534be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  void InitStackHwm();
535be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
5365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void NotifyLocked() {
5375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (wait_monitor_ != NULL) {
5385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      wait_cond_.Signal();
5395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
5405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
542be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void ThreadExitCallback(void* arg);
543b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
544aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers  void WalkStack(StackVisitor* visitor) const;
5454417536522fd2a9d8215d8672331984769c9520bShih-wei Liao
546bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void WalkStackUntilUpCall(StackVisitor* visitor) const;
547bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
548dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Thin lock thread id. This is a small integer used by the thin lock implementation.
549dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // This is not to be confused with the native thread's tid, nor is it the value returned
550dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
551dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // important difference between this id and the ids visible to managed code is that these
552dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // ones get reused (to ensure that they fit in the number of bits available).
553dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t thin_lock_id_;
554b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
555d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // System thread id.
556d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t tid_;
557d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
558d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // Native thread handle.
559be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  pthread_t pthread_;
560d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
561dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Our managed peer (an instance of java.lang.Thread).
562d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* peer_;
5638daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
5648daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Guards the 'interrupted_' and 'wait_monitor_' members.
5658daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  mutable Mutex wait_mutex_;
5665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  ConditionVariable wait_cond_;
5678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Pointer to the monitor lock we're currently waiting on (or NULL), guarded by wait_mutex_.
5688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  Monitor* wait_monitor_;
5698daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Thread "interrupted" status; stays raised until queried or thrown, guarded by wait_mutex_.
5708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool interrupted_;
5715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // The next thread in the wait set this thread is part of.
5725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* wait_next_;
5735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  friend class Monitor;
575dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
576c143c55718342519db5398e41dda31422cf16c79buzbee  // FIXME: placeholder for the gc cardTable
577c143c55718342519db5398e41dda31422cf16c79buzbee  uint32_t card_table_;
578c143c55718342519db5398e41dda31422cf16c79buzbee
579449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
580449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // We leave extra space so there's room for the code that throws StackOverflowError.
581449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  byte* stack_end_;
582be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
58345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // Top of the managed stack, written out prior to the state transition from
58445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // kRunnable to kNative. Uses include to give the starting point for scanning
58545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // a managed stack when a thread is in native code.
5861a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame top_of_managed_stack_;
58745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
588bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // PC corresponding to the call out of the top_of_managed_stack_ frame
589bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t top_of_managed_stack_pc_;
590bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
5916de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // A linked list (of stack allocated records) recording transitions from
5926de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // native to managed code.
5936de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  NativeToManagedRecord* native_to_managed_record_;
5946de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
595408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Top of linked list of stack indirect reference tables or NULL for none
596408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* top_sirt_;
597b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
598b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Every thread may have an associated JNI environment
59969f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* jni_env_;
600b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
60193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  volatile State state_;
602b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
60369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // Initialized to "this". On certain architectures (such as x86) reading
60469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // off of Thread::Current is easy but getting the address of Thread::Current
60569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // is hard. This field can be read off of Thread::Current to give the address.
60669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Thread* self_;
60769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
60869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Runtime* runtime_;
60969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
61069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // The pending exception or NULL.
611e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* exception_;
6120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
61345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // A non-zero value is used to tell the current thread to enter a safe point
61445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // at the next poll.
61545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  int suspend_count_;
61645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
617edcc09c737b00462881f147602656739d029571eElliott Hughes  // Needed to get the right ClassLoader in JNI_OnLoad, but also
618edcc09c737b00462881f147602656739d029571eElliott Hughes  // useful for testing.
619bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* class_loader_override_;
620c143c55718342519db5398e41dda31422cf16c79buzbee
621bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
622bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  UniquePtr<Context> long_jump_context_;
623bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
62469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // TLS key used to retrieve the VM thread object.
625b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static pthread_key_t pthread_key_self_;
626b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
62745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // Entry point called when exception_ is set
62845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void (*exception_entry_point_)(Method** frame);
62945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
63045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // Entry point called when suspend_count_ is non-zero
63145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  void (*suspend_count_entry_point_)(Method** frame);
63245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
6330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Thread);
6340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
635bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
636330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread);
637b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state);
6380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
639ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange {
640ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public:
641ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) {
642ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    old_thread_state_ = thread_->SetState(new_state);
643ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
644ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
645ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ~ScopedThreadStateChange() {
646ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    thread_->SetState(old_thread_state_);
647ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
648ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
649ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private:
650ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread* thread_;
651ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread::State old_thread_state_;
652ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange);
653ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes};
654ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
6550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
6560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_THREAD_H_
658