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