thread.h revision dcc247493fd8fb243e335c3ec08e5e625896a47c
10e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 20e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 30e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_THREAD_H_ 40e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_THREAD_H_ 50e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 6b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <pthread.h> 7a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 8a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iosfwd> 9b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <list> 10b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "dex_file.h" 12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h" 1369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes#include "jni_internal.h" 14578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h" 15578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h" 16b765be0d656c3073402693aeaf64e95a0e49f218Brian Carlstrom#include "mem_map.h" 17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h" 18b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art { 200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2169f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array; 2237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class; 231f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker; 24edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader; 25a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method; 260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object; 27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime; 280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread; 29b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList; 30e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughesclass Throwable; 3155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement; 321da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase; 331da522de18ac6e4c2913c3233529e9dd115059f8buzbee 3455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray; 354417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray; 364417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray; 370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Mutex { 390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro virtual ~Mutex() {} 410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 42b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Lock(); 430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 44b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro bool TryLock(); 450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 46b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unlock(); 470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const char* GetName() { return name_; } 490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Thread* GetOwner() { return owner_; } 510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 52b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static Mutex* Create(const char* name); 53b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 5479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // TODO: only needed because we lack a condition variable abstraction. 5579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes pthread_mutex_t* GetImpl() { return &lock_impl_; } 560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 5818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes explicit Mutex(const char* name) : name_(name), owner_(NULL) {} 5918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 6079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void SetOwner(Thread* thread) { owner_ = thread; } 6179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const char* name_; 630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Thread* owner_; 650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 66b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro pthread_mutex_t lock_impl_; 67b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 680e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Mutex); 690e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 700e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 710e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass MutexLock { 720e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 730e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro explicit MutexLock(Mutex *mu) : mu_(mu) { 740e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro mu_->Lock(); 750e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro ~MutexLock() { mu_->Unlock(); } 770e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 780e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Mutex* const mu_; 790e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(MutexLock); 800e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 810e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 82408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// Stack allocated indirect reference table, allocated within the bridge frame 83408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers// between managed and native code. 84408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogersclass StackIndirectReferenceTable { 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 86408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Number of references contained within this SIRT 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t NumberOfReferences() { 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return number_of_references_; 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 91408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Link to previous SIRT or NULL 92408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable* Link() { 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return link_; 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 96408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object** References() { 97408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return references_; 98a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 99a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 100408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Offset of length within SIRT, used by generated code 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static size_t NumberOfReferencesOffset() { 102408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_); 103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 105408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Offset of link within SIRT, used by generated code 106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static size_t LinkOffset() { 107408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_); 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 111408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable() {} 112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t number_of_references_; 114408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable* link_; 115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 116a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers // Fake array, really allocated and filled in by jni_compiler. 117408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object* references_[0]; 118a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 119408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable); 120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1226de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogersstruct NativeToManagedRecord { 1236de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers NativeToManagedRecord* link; 1246de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers void* last_top_of_managed_stack; 1256de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers}; 1266de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers 1271a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao// Iterator over managed frames up to the first native-to-managed transition 1281a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liaoclass Frame { 1299b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 1301a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame() : sp_(NULL) {} 1311a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1320cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Method* GetMethod() const { 133a09576416788b916095739e43a16917e7948f3a4Elliott Hughes return (sp_ != NULL) ? *sp_ : NULL; 1341a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 1351a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1361a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao bool HasNext() const { 1371a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao return NextMethod() != NULL; 1381a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 1391a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1401a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void Next(); 1411a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 14255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao uintptr_t GetPC() const; 1431a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1440cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Method** GetSP() const { 1451a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao return sp_; 1461a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 1471a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1481a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // TODO: this is here for testing, remove when we have exception unit tests 1491a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // that use the real stack 1500cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void SetSP(Method** sp) { 1511a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao sp_ = sp; 1521a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 1531a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1541a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao private: 1550cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Method* NextMethod() const; 1561a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1571a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao friend class Thread; 1581a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1590cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Method** sp_; 1601a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao}; 1611a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 1620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread { 1630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 164b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro enum State { 165b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kUnknown = -1, 166b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kNew, 167b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kRunnable, 168b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kBlocked, 169b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kWaiting, 170b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kTimedWaiting, 171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNative, 172b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kTerminated, 173b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro }; 174b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 175c143c55718342519db5398e41dda31422cf16c79buzbee 17661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const size_t kDefaultStackSize = 64 * KB; 17761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 178c143c55718342519db5398e41dda31422cf16c79buzbee // Runtime support function pointers 1794a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee void (*pDebugMe)(Method*, uint32_t); 180c143c55718342519db5398e41dda31422cf16c79buzbee void* (*pMemcpy)(void*, const void*, size_t); 1815433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pShlLong)(uint64_t, uint32_t); 1825433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pShrLong)(uint64_t, uint32_t); 1835433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pUshrLong)(uint64_t, uint32_t); 184c143c55718342519db5398e41dda31422cf16c79buzbee float (*pI2f)(int); 185c143c55718342519db5398e41dda31422cf16c79buzbee int (*pF2iz)(float); 186c143c55718342519db5398e41dda31422cf16c79buzbee float (*pD2f)(double); 187c143c55718342519db5398e41dda31422cf16c79buzbee double (*pF2d)(float); 188c143c55718342519db5398e41dda31422cf16c79buzbee double (*pI2d)(int); 189c143c55718342519db5398e41dda31422cf16c79buzbee int (*pD2iz)(double); 190c143c55718342519db5398e41dda31422cf16c79buzbee float (*pL2f)(long); 191c143c55718342519db5398e41dda31422cf16c79buzbee double (*pL2d)(long); 1921b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee long long (*pF2l)(float); 1931b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee long long (*pD2l)(double); 194c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFadd)(float, float); 195c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFsub)(float, float); 196c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFdiv)(float, float); 197c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFmul)(float, float); 198c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFmodf)(float, float); 199c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDadd)(double, double); 200c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDsub)(double, double); 201c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDdiv)(double, double); 202c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDmul)(double, double); 203c143c55718342519db5398e41dda31422cf16c79buzbee double (*pFmod)(double, double); 204c143c55718342519db5398e41dda31422cf16c79buzbee int (*pIdivmod)(int, int); 205c143c55718342519db5398e41dda31422cf16c79buzbee int (*pIdiv)(int, int); 206439c4fa0db980fb19e4a585723a64a3461e4c278buzbee long long (*pLmul)(long long, long long); 207c143c55718342519db5398e41dda31422cf16c79buzbee long long (*pLdivmod)(long long, long long); 208dfd3d70e58c37b5d56eded3a4469082d8bb26ee0buzbee Array* (*pAllocFromCode)(uint32_t, Method*, int32_t); 2091da522de18ac6e4c2913c3233529e9dd115059f8buzbee Array* (*pCheckAndAllocFromCode)(uint32_t, Method*, int32_t); 2101f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom Object* (*pAllocObjectFromCode)(uint32_t, Method*); 211e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee uint32_t (*pGet32Static)(uint32_t, const Method*); 212e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee void (*pSet32Static)(uint32_t, const Method*, uint32_t); 213e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee uint64_t (*pGet64Static)(uint32_t, const Method*); 214e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee void (*pSet64Static)(uint32_t, const Method*, uint64_t); 215e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee Object* (*pGetObjStatic)(uint32_t, const Method*); 216e1931749814dbb80c5a756f9842e9c261bb2e8f6buzbee void (*pSetObjStatic)(uint32_t, const Method*, Object*); 2170f4c41d75c821162184501cd4b510a93f6eb580fElliott Hughes void (*pCanPutArrayElementFromCode)(const Class*, const Class*); 2181b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee int (*pInstanceofNonTrivialFromCode) (const Class*, const Class*); 2191b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); 2201b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee bool (*pUnlockObjectFromCode)(Thread*, Object*); 2211b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee void (*pLockObjectFromCode)(Thread*, Object*); 2221b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee void (*pThrowException)(Thread*, Throwable*); 2231b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee void (*pHandleFillArrayDataFromCode)(Array*, const uint16_t*); 2241b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee Class* (*pInitializeTypeFromCode)(uint32_t, Method*); 225561227c80077bbb4147f778043f1a836af6b9248buzbee void (*pResolveMethodFromCode)(Method*, uint32_t); 2264a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee void (*pInvokeInterfaceTrampoline)(void*, void*, void*, void*); 2271da522de18ac6e4c2913c3233529e9dd115059f8buzbee StaticStorageBase* (*pInitializeStaticStorage)(uint32_t, const Method*); 228c143c55718342519db5398e41dda31422cf16c79buzbee 2299b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao class StackVisitor { 2309b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 2310cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers virtual ~StackVisitor() {} 2329b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao virtual bool VisitFrame(const Frame& frame) = 0; 2339b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao }; 2349b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 23561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread. 236b765be0d656c3073402693aeaf64e95a0e49f218Brian Carlstrom static Thread* Create(const Runtime* runtime); 23761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 23861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread from the calling thread. 239dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon); 240b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 241b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static Thread* Current() { 242d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro void* thread = pthread_getspecific(Thread::pthread_key_self_); 243d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro return reinterpret_cast<Thread*>(thread); 2440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 246a09576416788b916095739e43a16917e7948f3a4Elliott Hughes void Dump(std::ostream& os) const; 247a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 2480cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers State GetState() const { 2490cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return state_; 2500cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2510cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2520cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers State SetState(State new_state) { 2530cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers State old_state = state_; 2540cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers state_ = new_state; 2550cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return old_state; 2560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2580cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool CanAccessDirectReferences() const { 259a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes // TODO: when we have a moving collector, we'll need: return state_ == kRunnable; 260a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes return true; 2610cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2620cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 263dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t GetThinLockId() const { 264dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return thin_lock_id_; 265b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 266b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 267d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t GetTid() const { 268d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes return tid_; 269d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 270e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 271e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes pthread_t GetImpl() const { 272e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes return handle_; 2730e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2740e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2750cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // Returns the Method* for the current method. 2760cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // This is used by the JNI implementation for logging and diagnostic purposes. 2770cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers const Method* GetCurrentMethod() const { 2780cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return top_of_managed_stack_.GetMethod(); 2790cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2800cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2810e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool IsExceptionPending() const { 282b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes return exception_ != NULL; 2830e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2840e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 285e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes Throwable* GetException() const { 2860cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 2870e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro return exception_; 2880e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void SetException(Throwable* new_exception) { 2910cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 2920cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers CHECK(new_exception != NULL); 2930cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: CHECK(exception_ == NULL); 2940cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = new_exception; // TODO 2950cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2960cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2970cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void ClearException() { 2980cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = NULL; 299a09576416788b916095739e43a16917e7948f3a4Elliott Hughes } 300a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 3011a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame GetTopOfStack() const { 3021a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao return top_of_managed_stack_; 3031a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 3041a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 3051a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // TODO: this is here for testing, remove when we have exception unit tests 3061a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // that use the real stack 3071a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void SetTopOfStack(void* stack) { 3080cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack)); 3090e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 3100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 311e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes void ThrowNewException(const char* exception_class_descriptor, const char* fmt, ...) 312a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes __attribute__ ((format(printf, 3, 4))); 313a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes 31479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // This exception is special, because we need to pre-allocate an instance. 31579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void ThrowOutOfMemoryError(); 31679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3171a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame FindExceptionHandler(void* throw_pc, void** handler_pc); 3181a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 3191a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* FindExceptionHandlerInMethod(const Method* method, 3201a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* throw_pc, 3211a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao const DexFile& dex_file, 3221a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao ClassLinker* class_linker); 323668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao static ThreadOffset SelfOffset() { 324668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao return ThreadOffset(OFFSETOF_MEMBER(Thread, self_)); 325668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao } 3261a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 327dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Offset of exception_ within Thread, used by generated code 32845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers static ThreadOffset ExceptionOffset() { 32945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_)); 33045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 33145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 332dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Offset of thin_lock_id_ within Thread, used by generated code 333c143c55718342519db5398e41dda31422cf16c79buzbee static ThreadOffset IdOffset() { 334dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_)); 335c143c55718342519db5398e41dda31422cf16c79buzbee } 336c143c55718342519db5398e41dda31422cf16c79buzbee 337c143c55718342519db5398e41dda31422cf16c79buzbee // Offset of card_table within Thread, used by generated code 338c143c55718342519db5398e41dda31422cf16c79buzbee static ThreadOffset CardTableOffset() { 339c143c55718342519db5398e41dda31422cf16c79buzbee return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_)); 340c143c55718342519db5398e41dda31422cf16c79buzbee } 341c143c55718342519db5398e41dda31422cf16c79buzbee 342b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void SetName(const char* name); 343b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 344b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Suspend(); 345b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 346b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro bool IsSuspended(); 347b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 348b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Resume(); 349b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 350c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes static bool Startup(); 351c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes static void Shutdown(); 352b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 35345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers static ThreadOffset SuspendCountOffset() { 35445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_)); 35545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 35645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 357b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of state within Thread, used by generated code 358b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static ThreadOffset StateOffset() { 359b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, state_)); 360b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 361b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 362b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // JNI methods 36369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes JNIEnvExt* GetJniEnv() const { 364b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return jni_env_; 365b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 366b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 367b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of JNI environment within Thread, used by generated code 368b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static ThreadOffset JniEnvOffset() { 369b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 370b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 371b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 37245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Offset of top of managed stack address, used by generated code 37345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers static ThreadOffset TopOfManagedStackOffset() { 3741a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) + 3751a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao OFFSETOF_MEMBER(Frame, sp_)); 37645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 37745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 378408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Offset of top stack indirect reference table within Thread, used by 379408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // generated code 380408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers static ThreadOffset TopSirtOffset() { 381408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); 382b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 383b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 384408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Number of references allocated in SIRTs on this thread 385408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers size_t NumSirtReferences(); 386a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 387408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Is the given obj in this thread's stack indirect reference table? 388408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers bool SirtContains(jobject obj); 389408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 390408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Convert a jobject into a Object* 391408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object* DecodeJObject(jobject obj); 392b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 39345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Offset of exception_entry_point_ within Thread, used by generated code 39445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers static ThreadOffset ExceptionEntryPointOffset() { 39545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_entry_point_)); 39645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 39745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 39845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void RegisterExceptionEntryPoint(void (*handler)(Method**)) { 39945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers exception_entry_point_ = handler; 40045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 40145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 40245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Offset of suspend_count_entry_point_ within Thread, used by generated code 40345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers static ThreadOffset SuspendCountEntryPointOffset() { 40445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_entry_point_)); 40545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 40645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 40745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void RegisterSuspendCountEntryPoint(void (*handler)(Method**)) { 40845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers suspend_count_entry_point_ = handler; 40945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers } 41045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 41145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Increasing the suspend count, will cause the thread to run to safepoint 41245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void IncrementSuspendCount() { suspend_count_++; } 41345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void DecrementSuspendCount() { suspend_count_--; } 41445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 4156de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // Linked list recording transitions from native to managed code 4166de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers void PushNativeToManagedRecord(NativeToManagedRecord* record) { 4171a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao record->last_top_of_managed_stack = reinterpret_cast<void*>(top_of_managed_stack_.GetSP()); 4186de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers record->link = native_to_managed_record_; 4196de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers native_to_managed_record_ = record; 4201a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao top_of_managed_stack_.SetSP(NULL); 4216de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers } 4226de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers void PopNativeToManagedRecord(const NativeToManagedRecord& record) { 4236de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers native_to_managed_record_ = record.link; 4240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(record.last_top_of_managed_stack)); 4256de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers } 4266de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers 427bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom const ClassLoader* GetClassLoaderOverride() { 4280cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: need to place the class_loader_override_ in a handle 4290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // DCHECK(CanAccessDirectReferences()); 430c143c55718342519db5398e41dda31422cf16c79buzbee return class_loader_override_; 431c143c55718342519db5398e41dda31422cf16c79buzbee } 432c143c55718342519db5398e41dda31422cf16c79buzbee 433bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom void SetClassLoaderOverride(const ClassLoader* class_loader_override) { 434c143c55718342519db5398e41dda31422cf16c79buzbee class_loader_override_ = class_loader_override; 435c143c55718342519db5398e41dda31422cf16c79buzbee } 436c143c55718342519db5398e41dda31422cf16c79buzbee 4374417536522fd2a9d8215d8672331984769c9520bShih-wei Liao // Allocate stack trace 4389b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao ObjectArray<StackTraceElement>* AllocStackTrace(); 43955df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 440410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 441410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 4420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 443dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes Thread(); 444c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes ~Thread(); 4450cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers friend class Runtime; // For ~Thread. 4460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 447d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void DumpState(std::ostream& os) const; 448d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void DumpStack(std::ostream& os) const; 449d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 450b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void InitCpu(); 4513ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee void InitFunctionPointers(); 452b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 4539b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao void WalkStack(StackVisitor* visitor); 4544417536522fd2a9d8215d8672331984769c9520bShih-wei Liao 455dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Thin lock thread id. This is a small integer used by the thin lock implementation. 456dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // This is not to be confused with the native thread's tid, nor is it the value returned 457dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One 458dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // important difference between this id and the ids visible to managed code is that these 459dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // ones get reused (to ensure that they fit in the number of bits available). 460dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t thin_lock_id_; 461b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 462d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // System thread id. 463d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t tid_; 464d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 465d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // Native thread handle. 466d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pthread_t handle_; 467d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 468dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes bool is_daemon_; 469dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 470dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Our managed peer (an instance of java.lang.Thread). 471dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes Object* peer_; 472dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 473c143c55718342519db5398e41dda31422cf16c79buzbee // FIXME: placeholder for the gc cardTable 474c143c55718342519db5398e41dda31422cf16c79buzbee uint32_t card_table_; 475c143c55718342519db5398e41dda31422cf16c79buzbee 47645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Top of the managed stack, written out prior to the state transition from 47745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // kRunnable to kNative. Uses include to give the starting point for scanning 47845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // a managed stack when a thread is in native code. 4791a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame top_of_managed_stack_; 48045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 4816de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // A linked list (of stack allocated records) recording transitions from 4826de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // native to managed code. 4836de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers NativeToManagedRecord* native_to_managed_record_; 4846de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers 485408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Top of linked list of stack indirect reference tables or NULL for none 486408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable* top_sirt_; 487b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 488b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Every thread may have an associated JNI environment 48969f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes JNIEnvExt* jni_env_; 490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 491b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro State state_; 492b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 49369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Initialized to "this". On certain architectures (such as x86) reading 49469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // off of Thread::Current is easy but getting the address of Thread::Current 49569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // is hard. This field can be read off of Thread::Current to give the address. 49669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Thread* self_; 49769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 49869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Runtime* runtime_; 49969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 50069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // The pending exception or NULL. 501e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes Throwable* exception_; 5020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 50345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // A non-zero value is used to tell the current thread to enter a safe point 50445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // at the next poll. 50545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers int suspend_count_; 50645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 507edcc09c737b00462881f147602656739d029571eElliott Hughes // Needed to get the right ClassLoader in JNI_OnLoad, but also 508edcc09c737b00462881f147602656739d029571eElliott Hughes // useful for testing. 509bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom const ClassLoader* class_loader_override_; 510c143c55718342519db5398e41dda31422cf16c79buzbee 51169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // TLS key used to retrieve the VM thread object. 512b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static pthread_key_t pthread_key_self_; 513b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 51445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Entry point called when exception_ is set 51545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void (*exception_entry_point_)(Method** frame); 51645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 51745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // Entry point called when suspend_count_ is non-zero 51845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers void (*suspend_count_entry_point_)(Method** frame); 51945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 5200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Thread); 5210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 522330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread); 523b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state); 5240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 525b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList { 526b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro public: 52761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kMaxId = 0xFFFF; 52861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kInvalidId = 0; 52961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kMainId = 1; 53061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 53161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static ThreadList* Create(); 532b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 53361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro ~ThreadList(); 534b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 535d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void Dump(std::ostream& os); 536d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 537b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Register(Thread* thread); 538b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 539b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unregister(Thread* thread); 540b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 541c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes bool Contains(Thread* thread); 542c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 543b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Lock() { 544b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro lock_->Lock(); 545b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 546b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 547b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unlock() { 548b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro lock_->Unlock(); 549b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro }; 550b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 551410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 552410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 553b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro private: 554b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadList(); 555b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 556b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro std::list<Thread*> list_; 557b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 558b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro Mutex* lock_; 559b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 560b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ThreadList); 561b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro}; 562b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 563b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadListLock { 564b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro public: 565b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadListLock(ThreadList* thread_list, Thread* current_thread) 566b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro : thread_list_(thread_list) { 567b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread == NULL) { // try to get it from TLS 568b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro current_thread = Thread::Current(); 569b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 570b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro Thread::State old_state; 571b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread != NULL) { 572ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes old_state = current_thread->SetState(Thread::kWaiting); // TODO: VMWAIT 573b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } else { 574b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // happens during VM shutdown 575b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro old_state = Thread::kUnknown; // TODO: something else 576b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 577b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro thread_list_->Lock(); 578b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread != NULL) { 579b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro current_thread->SetState(old_state); 580b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 581b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 582b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 583b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ~ThreadListLock() { 584b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro thread_list_->Unlock(); 585b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 586b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 587b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro private: 588b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadList* thread_list_; 589b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 590b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ThreadListLock); 591b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro}; 592b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 593ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange { 594ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public: 595ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) { 596ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes old_thread_state_ = thread_->SetState(new_state); 597ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes } 598ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 599ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes ~ScopedThreadStateChange() { 600ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes thread_->SetState(old_thread_state_); 601ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes } 602ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 603ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private: 604ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread* thread_; 605ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread::State old_thread_state_; 606ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange); 607ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes}; 608ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 6090e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 6100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 6110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_THREAD_H_ 612