thread.h revision 8e4aac52962d54cb4be2078b9cd95685e067133a
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"
359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "runtime_stats.h"
36bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h"
37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art {
390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
4069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array;
4137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class;
421f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker;
43edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader;
44bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context;
45a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method;
468daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor;
470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object;
48b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime;
490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread;
50b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList;
51e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughesclass Throwable;
5255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement;
531da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase;
541da522de18ac6e4c2913c3233529e9dd115059f8buzbee
5555df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray;
564417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray;
574417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray;
580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
59408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// Stack allocated indirect reference table, allocated within the bridge frame
60408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// between managed and native code.
61408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogersclass StackIndirectReferenceTable {
62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public:
63408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Number of references contained within this SIRT
64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  size_t NumberOfReferences() {
65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return number_of_references_;
66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
68408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Link to previous SIRT or NULL
69408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* Link() {
70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return link_;
71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
73408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object** References() {
74408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return references_;
75a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers  }
76a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
77408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Offset of length within SIRT, used by generated code
78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  static size_t NumberOfReferencesOffset() {
79408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_);
80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
82408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Offset of link within SIRT, used by generated code
83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  static size_t LinkOffset() {
84408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_);
85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private:
88408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable() {}
89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  size_t number_of_references_;
91408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* link_;
92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
93a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers  // Fake array, really allocated and filled in by jni_compiler.
94408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* references_[0];
95a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
96408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable);
97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers};
98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
996de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogersstruct NativeToManagedRecord {
100bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  NativeToManagedRecord* link_;
101bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void* last_top_of_managed_stack_;
102bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t last_top_of_managed_stack_pc_;
1036de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers};
1046de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
1051a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao// Iterator over managed frames up to the first native-to-managed transition
10685d1545e985ac689db4bad7849880e843707c862Elliott Hughesclass PACKED Frame {
1079b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public:
1081a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame() : sp_(NULL) {}
1091a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method* GetMethod() const {
111a09576416788b916095739e43a16917e7948f3a4Elliott Hughes    return (sp_ != NULL) ? *sp_ : NULL;
1121a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1131a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1141a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  bool HasNext() const {
1151a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return NextMethod() != NULL;
1161a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1171a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1181a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void Next();
1191a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
120bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t GetReturnPC() const;
121bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
122bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  uintptr_t LoadCalleeSave(int num) const;
1231a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method** GetSP() const {
1251a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return sp_;
1261a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1271a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1281a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // TODO: this is here for testing, remove when we have exception unit tests
1291a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // that use the real stack
1300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetSP(Method** sp) {
1311a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    sp_ = sp;
1321a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
1331a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1349086572fa809d1a19d886b467e4da3ce42016982Ian Rogers  // Is this a frame for a real method (native or with dex code)
1359086572fa809d1a19d886b467e4da3ce42016982Ian Rogers  bool HasMethod() const;
1369086572fa809d1a19d886b467e4da3ce42016982Ian Rogers
1371a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao private:
1380cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method* NextMethod() const;
1391a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1401a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  friend class Thread;
1411a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
1420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  Method** sp_;
1431a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao};
1441a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
14585d1545e985ac689db4bad7849880e843707c862Elliott Hughesclass PACKED Thread {
1460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public:
1478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /* thread priorities, from java.lang.Thread */
1488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  enum Priority {
1498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMinPriority = 1,
1508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kNormPriority = 5,
1518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    kMaxPriority = 10,
1528daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  };
153b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  enum State {
15493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    // These match up with JDWP values.
15593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kTerminated   = 0,        // TERMINATED
15693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kRunnable     = 1,        // RUNNABLE or running now
15793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kTimedWaiting = 2,        // TIMED_WAITING in Object.wait()
15893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kBlocked      = 3,        // BLOCKED on a monitor
15993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kWaiting      = 4,        // WAITING in Object.wait()
16093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    // Non-JDWP states.
16193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kInitializing = 5,        // allocated, not yet running --- TODO: unnecessary?
16293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kStarting     = 6,        // native thread started, not yet ready to run managed code
16393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kNative       = 7,        // off in a JNI native method
16493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kVmWait       = 8,        // waiting on a VM resource
16593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    kSuspended    = 9,        // suspended, usually by GC or debugger
166b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  };
167b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
168932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Space to throw a StackOverflowError in.
169932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  static const size_t kStackOverflowReservedBytes = 3 * KB;
170c143c55718342519db5398e41dda31422cf16c79buzbee
17161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  static const size_t kDefaultStackSize = 64 * KB;
17261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
173c143c55718342519db5398e41dda31422cf16c79buzbee  // Runtime support function pointers
1744a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee  void (*pDebugMe)(Method*, uint32_t);
175c143c55718342519db5398e41dda31422cf16c79buzbee  void* (*pMemcpy)(void*, const void*, size_t);
1765433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pShlLong)(uint64_t, uint32_t);
1775433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pShrLong)(uint64_t, uint32_t);
1785433072f589b61413e042eddf76e8190a048f71dbuzbee  uint64_t (*pUshrLong)(uint64_t, uint32_t);
179c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pI2f)(int);
180c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pF2iz)(float);
181c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pD2f)(double);
182c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pF2d)(float);
183c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pI2d)(int);
184c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pD2iz)(double);
185c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pL2f)(long);
186c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pL2d)(long);
1871b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  long long (*pF2l)(float);
1881b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  long long (*pD2l)(double);
189c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFadd)(float, float);
190c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFsub)(float, float);
191c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFdiv)(float, float);
192c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFmul)(float, float);
193c143c55718342519db5398e41dda31422cf16c79buzbee  float (*pFmodf)(float, float);
194c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDadd)(double, double);
195c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDsub)(double, double);
196c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDdiv)(double, double);
197c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pDmul)(double, double);
198c143c55718342519db5398e41dda31422cf16c79buzbee  double (*pFmod)(double, double);
199c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pIdivmod)(int, int);
200c143c55718342519db5398e41dda31422cf16c79buzbee  int (*pIdiv)(int, int);
201439c4fa0db980fb19e4a585723a64a3461e4c278buzbee  long long (*pLmul)(long long, long long);
202c143c55718342519db5398e41dda31422cf16c79buzbee  long long (*pLdivmod)(long long, long long);
20321d9e8323124a832a21679ca83808bc9c68ed365Ian Rogers  void* (*pAllocObjectFromCode)(uint32_t, void*);
204b886da8e3c26443ab4d2aa63268bd673c354c3d2Ian Rogers  void* (*pArrayAllocFromCode)(uint32_t, void*, int32_t);
205b886da8e3c26443ab4d2aa63268bd673c354c3d2Ian Rogers  void* (*pCheckAndArrayAllocFromCode)(uint32_t, void*, int32_t);
206e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  uint32_t (*pGet32Static)(uint32_t, const Method*);
207e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSet32Static)(uint32_t, const Method*, uint32_t);
208e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  uint64_t (*pGet64Static)(uint32_t, const Method*);
209e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSet64Static)(uint32_t, const Method*, uint64_t);
210e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  Object* (*pGetObjStatic)(uint32_t, const Method*);
211e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee  void (*pSetObjStatic)(uint32_t, const Method*, Object*);
212e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers  void (*pCanPutArrayElementFromCode)(void*, void*);
2132a475e7b93d754e0a7525bb5c7059386307ea63abuzbee  bool (*pInstanceofNonTrivialFromCode) (const Object*, const Class*);
214ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void (*pCheckCastFromCode) (void*, void*);
2151b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*);
216ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void (*pUnlockObjectFromCode)(void*, void*);
2171b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  void (*pLockObjectFromCode)(Thread*, Object*);
21867375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  void (*pDeliverException)(void*);
219ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void (*pHandleFillArrayDataFromCode)(void*, void*);
2201b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee  Class* (*pInitializeTypeFromCode)(uint32_t, Method*);
221561227c80077bbb4147f778043f1a836af6b9248buzbee  void (*pResolveMethodFromCode)(Method*, uint32_t);
2224a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee  void (*pInvokeInterfaceTrampoline)(void*, void*, void*, void*);
223cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers  void* (*pInitializeStaticStorage)(uint32_t, void*);
224845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom  Field* (*pFindInstanceFieldFromCode)(uint32_t, const Method*);
2250d966cff87464544a264efdbfba6c379474d5928buzbee  void (*pCheckSuspendFromCode)(Thread*);
226c1f45048b90a85018c6b063c31bc088dc3dd993dbuzbee  void (*pTestSuspendFromCode)();
227932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void (*pThrowStackOverflowFromCode)(void*);
2285ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNullPointerFromCode)();
2295ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
2305ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowDivZeroFromCode)();
2315ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowVerificationErrorFromCode)(int32_t, int32_t);
2325ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNegArraySizeFromCode)(int32_t);
2335ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowRuntimeExceptionFromCode)(int32_t);
2345ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowInternalErrorFromCode)(int32_t);
2355ade1d255ef1b5022321ac20493208703b34d2b1buzbee  void (*pThrowNoSuchMethodFromCode)(int32_t);
236ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp);
237161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  void* (*pFindNativeMethod)(Thread* thread);
238161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj);
239c143c55718342519db5398e41dda31422cf16c79buzbee
2409b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  class StackVisitor {
2419b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao   public:
2420cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    virtual ~StackVisitor() {}
243bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    virtual void VisitFrame(const Frame& frame, uintptr_t pc) = 0;
2449b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao  };
2459b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao
24661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread.
247d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  static void Create(Object* peer, size_t stack_size);
24861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro
24961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro  // Creates a new thread from the calling thread.
250dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon);
251b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
252b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static Thread* Current() {
253d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    void* thread = pthread_getspecific(Thread::pthread_key_self_);
254d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro    return reinterpret_cast<Thread*>(thread);
2550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
2560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
25701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static Thread* FromManagedThread(JNIEnv* env, jobject thread);
2588e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  static uint32_t LockOwnerFromThreadLock(Object* thread_lock);
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
268038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  bool IsDaemon();
269038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes
2708d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  void WaitUntilSuspended();
2710cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
2725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool HoldsLock(Object*);
2735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2748daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Changes the priority of this thread to match that of the java.lang.Thread object.
2768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * We map a priority value from 1-10 to Linux "nice" values, where lower
2788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * numbers indicate higher priority.
2798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  void SetNativePriority(int newPriority);
2818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2828daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  /*
2838daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns the thread priority for the current thread by querying the system.
2848daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * This is useful when attaching a thread through JNI.
2858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   *
2868daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
2878daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes   */
2888daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static int GetNativePriority();
2898daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  bool CanAccessDirectReferences() const {
291a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    // TODO: when we have a moving collector, we'll need: return state_ == kRunnable;
292a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes    return true;
2930cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2940cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
295dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t GetThinLockId() const {
296dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    return thin_lock_id_;
297b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  }
298b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
299d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t GetTid() const {
300d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes    return tid_;
301d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  }
302e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes
303e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes  pthread_t GetImpl() const {
304be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return pthread_;
3050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3060e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
307d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* GetPeer() const {
3088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return peer_;
3098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
3108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats* GetStats() {
3129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    return &stats_;
3139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
3149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
3150cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // Returns the Method* for the current method.
3160cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  // This is used by the JNI implementation for logging and diagnostic purposes.
3170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  const Method* GetCurrentMethod() const {
3180cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    return top_of_managed_stack_.GetMethod();
3190cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
3200cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  bool IsExceptionPending() const {
322b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes    return exception_ != NULL;
3230e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
325e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* GetException() const {
3260cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
3270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro    return exception_;
3280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
3300cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void SetException(Throwable* new_exception) {
3310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    DCHECK(CanAccessDirectReferences());
3320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    CHECK(new_exception != NULL);
3330cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // TODO: CHECK(exception_ == NULL);
3340cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = new_exception;  // TODO
3350cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
3360cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
3370cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  void ClearException() {
3380cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    exception_ = NULL;
339a09576416788b916095739e43a16917e7948f3a4Elliott Hughes  }
340a09576416788b916095739e43a16917e7948f3a4Elliott Hughes
341bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Find catch block and perform long jump to appropriate exception handle
342ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers  void DeliverException();
343bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
344bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  Context* GetLongJumpContext();
345bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
3461a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame GetTopOfStack() const {
3471a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao    return top_of_managed_stack_;
3481a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  }
3491a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
3501a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // TODO: this is here for testing, remove when we have exception unit tests
3511a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  // that use the real stack
352bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStack(void* stack, uintptr_t pc) {
3530cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack));
354bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
3550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  }
3560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
357bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  void SetTopOfStackPC(uintptr_t pc) {
358bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    top_of_managed_stack_pc_ = pc;
359bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
360bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
361e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  void ThrowNewException(const char* exception_class_descriptor, const char* fmt, ...)
362a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes      __attribute__ ((format(printf, 3, 4)));
363a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes
3644a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes  void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap);
3654a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes
36679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // This exception is special, because we need to pre-allocate an instance.
36779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  void ThrowOutOfMemoryError();
36879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3691a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  Frame FindExceptionHandler(void* throw_pc, void** handler_pc);
3701a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao
3711a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao  void* FindExceptionHandlerInMethod(const Method* method,
3721a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     void* throw_pc,
3731a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     const DexFile& dex_file,
3741a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao                                     ClassLinker* class_linker);
375c143c55718342519db5398e41dda31422cf16c79buzbee
376b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  void SetName(const char* name);
377b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
378be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void Startup();
379038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes  static void FinishStartup();
380c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  static void Shutdown();
381b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
382b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // JNI methods
38369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* GetJniEnv() const {
384b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return jni_env_;
385b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
386b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
387408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Number of references allocated in SIRTs on this thread
388408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  size_t NumSirtReferences();
389a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers
390408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Is the given obj in this thread's stack indirect reference table?
391408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  bool SirtContains(jobject obj);
392408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers
39367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Pop the top SIRT
39467375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  void PopSirt();
39567375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers
396408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Convert a jobject into a Object*
397408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  Object* DecodeJObject(jobject obj);
398b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
3998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.interrupted.
4008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool Interrupted() {
40185d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
4028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    bool interrupted = interrupted_;
4038daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    interrupted_ = false;
4048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted;
4058daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
4068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
4078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Implements java.lang.Thread.isInterrupted.
4088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  bool IsInterrupted() {
40985d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
4108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    return interrupted_;
4118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
4128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
4135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Interrupt() {
41485d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
4155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (interrupted_) {
4165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
4175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
4185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    interrupted_ = true;
4195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
4205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void Notify() {
42385d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*wait_mutex_);
4245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    NotifyLocked();
4255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
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[]
45301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  jobject CreateInternalStackTrace(JNIEnv* env) const;
45401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes
45501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a
45601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many
45701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated
45801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  // with the number of valid frames in the returned array.
45901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes  static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
46001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes      jobjectArray output_array = NULL, int* stack_depth = NULL);
46155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao
462410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
463410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
464be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
465be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  // Offsets of various members of native Thread class, used by compiled code.
466be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  //
467be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
468be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SelfOffset() {
469be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, self_));
470be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
471be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
472be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset ExceptionOffset() {
473be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_));
474be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
475be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
47654e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  static ThreadOffset ThinLockIdOffset() {
477be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_));
478be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
479be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
480be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset CardTableOffset() {
481be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_));
482be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
483be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
484be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset SuspendCountOffset() {
485be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_));
486be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
487be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
488be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset StateOffset() {
48993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes    return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_));
490be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
491be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
492932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of stack less any space reserved for stack overflow
493932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  size_t GetStackSize() {
494932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    return stack_size_ - (stack_end_ - stack_base_);
495932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
496932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
497932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during a stack overflow
498932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void SetStackEndForStackOverflow() {
499932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // During stack overflow we allow use of the full stack
500932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    CHECK(stack_end_ != stack_base_) << "Need to increase: kStackOverflowReservedBytes ("
501932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers                                     << kStackOverflowReservedBytes << ")";
502932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    stack_end_ = stack_base_;
503932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
504932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
505932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Set the stack end to that to be used during regular execution
506932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  void ResetDefaultStackEnd() {
507932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room
508932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    // to throw a StackOverflowError.
509932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers    stack_end_ = stack_base_ + kStackOverflowReservedBytes;
510932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  }
511932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
512449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  static ThreadOffset StackEndOffset() {
513449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_));
514be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
515be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
516be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset JniEnvOffset() {
517be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_));
518be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
519be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
520be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopOfManagedStackOffset() {
521be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) +
522be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes        OFFSETOF_MEMBER(Frame, sp_));
523be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
524be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
525bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  static ThreadOffset TopOfManagedStackPcOffset() {
526bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_));
527bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  }
528bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
529be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static ThreadOffset TopSirtOffset() {
530be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes    return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_));
531be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  }
532be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
5339407c60800c95902fba0b3c3265520d47c1e7052Shih-wei Liao  void WalkStack(StackVisitor* visitor) const;
5349407c60800c95902fba0b3c3265520d47c1e7052Shih-wei Liao
5350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private:
536dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  Thread();
537c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes  ~Thread();
53802b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes  friend class ThreadList;  // For ~Thread.
5390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
5405fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  void CreatePeer(const char* name, bool as_daemon);
5415fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes  friend class Runtime; // For CreatePeer.
5425fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
543d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpState(std::ostream& os) const;
544d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  void DumpStack(std::ostream& os) const;
545d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
54693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  void Attach(const Runtime* runtime);
54793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  static void* CreateCallback(void* arg);
54893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
549b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  void InitCpu();
5503ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee  void InitFunctionPointers();
551be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  void InitStackHwm();
552be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
5535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  void NotifyLocked() {
5545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (wait_monitor_ != NULL) {
55585d1545e985ac689db4bad7849880e843707c862Elliott Hughes      wait_cond_->Signal();
5565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
5575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
559be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  static void ThreadExitCallback(void* arg);
560b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
56167375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  void WalkStackUntilUpCall(StackVisitor* visitor, bool include_upcall) const;
562bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
563dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Thin lock thread id. This is a small integer used by the thin lock implementation.
564dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // This is not to be confused with the native thread's tid, nor is it the value returned
565dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One
566dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // important difference between this id and the ids visible to managed code is that these
567dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // ones get reused (to ensure that they fit in the number of bits available).
568dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  uint32_t thin_lock_id_;
569b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
570d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // System thread id.
571d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  pid_t tid_;
572d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
573d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes  // Native thread handle.
574be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes  pthread_t pthread_;
575d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes
576dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes  // Our managed peer (an instance of java.lang.Thread).
577d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes  Object* peer_;
5788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
5798e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // The top_of_managed_stack_ and top_of_managed_stack_pc_ fields are accessed from
5808e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // compiled code, so we keep them early in the structure to (a) avoid having to keep
5818e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // fixing the assembler offsets and (b) improve the chances that these will still be aligned.
5828e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
5838e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // Top of the managed stack, written out prior to the state transition from
5848e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // kRunnable to kNative. Uses include to give the starting point for scanning
5858e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // a managed stack when a thread is in native code.
5868e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Frame top_of_managed_stack_;
5878e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // PC corresponding to the call out of the top_of_managed_stack_ frame
5888e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uintptr_t top_of_managed_stack_pc_;
5898e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
5908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Guards the 'interrupted_' and 'wait_monitor_' members.
59185d1545e985ac689db4bad7849880e843707c862Elliott Hughes  mutable Mutex* wait_mutex_;
59285d1545e985ac689db4bad7849880e843707c862Elliott Hughes  ConditionVariable* wait_cond_;
5938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Pointer to the monitor lock we're currently waiting on (or NULL), guarded by wait_mutex_.
5948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  Monitor* wait_monitor_;
5958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Thread "interrupted" status; stays raised until queried or thrown, guarded by wait_mutex_.
5968e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uint32_t interrupted_;
5975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // The next thread in the wait set this thread is part of.
5985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* wait_next_;
5998e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // If we're blocked in MonitorEnter, this is the object we're trying to lock.
6008e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Object* monitor_enter_object_;
6015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
6025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  friend class Monitor;
603dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
6049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  RuntimeStats stats_;
6059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
606c143c55718342519db5398e41dda31422cf16c79buzbee  // FIXME: placeholder for the gc cardTable
607c143c55718342519db5398e41dda31422cf16c79buzbee  uint32_t card_table_;
608c143c55718342519db5398e41dda31422cf16c79buzbee
609449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // The end of this thread's stack. This is the lowest safely-addressable address on the stack.
610449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  // We leave extra space so there's room for the code that throws StackOverflowError.
611449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes  byte* stack_end_;
612be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes
613932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // Size of the stack
614932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  size_t stack_size_;
615932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
616932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  // The "lowest addressable byte" of the stack
617932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers  byte* stack_base_;
618932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers
6196de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // A linked list (of stack allocated records) recording transitions from
6206de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  // native to managed code.
6216de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers  NativeToManagedRecord* native_to_managed_record_;
6226de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers
623408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  // Top of linked list of stack indirect reference tables or NULL for none
624408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers  StackIndirectReferenceTable* top_sirt_;
625b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
626b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // Every thread may have an associated JNI environment
62769f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes  JNIEnvExt* jni_env_;
628b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
62993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes  volatile State state_;
630b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
63169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // Initialized to "this". On certain architectures (such as x86) reading
63269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // off of Thread::Current is easy but getting the address of Thread::Current
63369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // is hard. This field can be read off of Thread::Current to give the address.
63469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Thread* self_;
63569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
63669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  Runtime* runtime_;
63769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro
63869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // The pending exception or NULL.
639e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  Throwable* exception_;
6400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
64145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // A non-zero value is used to tell the current thread to enter a safe point
64245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  // at the next poll.
64345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  int suspend_count_;
64445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
645edcc09c737b00462881f147602656739d029571eElliott Hughes  // Needed to get the right ClassLoader in JNI_OnLoad, but also
646edcc09c737b00462881f147602656739d029571eElliott Hughes  // useful for testing.
647bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom  const ClassLoader* class_loader_override_;
648c143c55718342519db5398e41dda31422cf16c79buzbee
649bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Thread local, lazily allocated, long jump context. Used to deliver exceptions.
65085d1545e985ac689db4bad7849880e843707c862Elliott Hughes  Context* long_jump_context_;
651bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
65269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro  // TLS key used to retrieve the VM thread object.
653b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro  static pthread_key_t pthread_key_self_;
654b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro
6550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro  DISALLOW_COPY_AND_ASSIGN(Thread);
6560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro};
657bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
658330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread);
659b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state);
6600e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
661ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange {
662ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public:
663ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) {
664ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    old_thread_state_ = thread_->SetState(new_state);
665ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
666ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
667ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  ~ScopedThreadStateChange() {
668ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    thread_->SetState(old_thread_state_);
669ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  }
670ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
671ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private:
672ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread* thread_;
673ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  Thread::State old_thread_state_;
674ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange);
675ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes};
676ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes
6770e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}  // namespace art
6780e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro
6790e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif  // ART_SRC_THREAD_H_
680