thread.h revision 40381fb9dc4b4cf274f1e58b2cdf4396202c6189
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" 3668e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h" 37bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers#include "UniquePtr.h" 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art { 400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 4169f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughesclass Array; 4237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughesclass Class; 431f87008b165d26541d832ff805250afdc89c253dBrian Carlstromclass ClassLinker; 44edcc09c737b00462881f147602656739d029571eElliott Hughesclass ClassLoader; 45bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersclass Context; 46a40f9bc48afe3a9d38be2fa298fece13ed82ba28Brian Carlstromclass Method; 478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass Monitor; 480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object; 49b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime; 5068e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughesclass StackIndirectReferenceTable; 5155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaoclass StackTraceElement; 521da522de18ac6e4c2913c3233529e9dd115059f8buzbeeclass StaticStorageBase; 5340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Thread; 5440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass ThreadList; 5540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromclass Throwable; 561da522de18ac6e4c2913c3233529e9dd115059f8buzbee 5755df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liaotemplate<class T> class ObjectArray; 584417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotemplate<class T> class PrimitiveArray; 594417536522fd2a9d8215d8672331984769c9520bShih-wei Liaotypedef PrimitiveArray<int32_t> IntArray; 600e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 6185d1545e985ac689db4bad7849880e843707c862Elliott Hughesclass PACKED Thread { 620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 638daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes /* thread priorities, from java.lang.Thread */ 648daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes enum Priority { 658daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes kMinPriority = 1, 668daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes kNormPriority = 5, 678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes kMaxPriority = 10, 688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes }; 69b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro enum State { 7093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // These match up with JDWP values. 7193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kTerminated = 0, // TERMINATED 7293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kRunnable = 1, // RUNNABLE or running now 7393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kTimedWaiting = 2, // TIMED_WAITING in Object.wait() 7493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kBlocked = 3, // BLOCKED on a monitor 7593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kWaiting = 4, // WAITING in Object.wait() 7693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // Non-JDWP states. 7793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kInitializing = 5, // allocated, not yet running --- TODO: unnecessary? 7893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kStarting = 6, // native thread started, not yet ready to run managed code 7993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kNative = 7, // off in a JNI native method 8093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kVmWait = 8, // waiting on a VM resource 8193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes kSuspended = 9, // suspended, usually by GC or debugger 82b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro }; 83b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 84932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Space to throw a StackOverflowError in. 85aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom static const size_t kStackOverflowReservedBytes = 4 * KB; 86c143c55718342519db5398e41dda31422cf16c79buzbee 8761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const size_t kDefaultStackSize = 64 * KB; 8861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 89c143c55718342519db5398e41dda31422cf16c79buzbee // Runtime support function pointers 904a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee void (*pDebugMe)(Method*, uint32_t); 91c143c55718342519db5398e41dda31422cf16c79buzbee void* (*pMemcpy)(void*, const void*, size_t); 925433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pShlLong)(uint64_t, uint32_t); 935433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pShrLong)(uint64_t, uint32_t); 945433072f589b61413e042eddf76e8190a048f71dbuzbee uint64_t (*pUshrLong)(uint64_t, uint32_t); 95c143c55718342519db5398e41dda31422cf16c79buzbee float (*pI2f)(int); 96c143c55718342519db5398e41dda31422cf16c79buzbee int (*pF2iz)(float); 97c143c55718342519db5398e41dda31422cf16c79buzbee float (*pD2f)(double); 98c143c55718342519db5398e41dda31422cf16c79buzbee double (*pF2d)(float); 99c143c55718342519db5398e41dda31422cf16c79buzbee double (*pI2d)(int); 100c143c55718342519db5398e41dda31422cf16c79buzbee int (*pD2iz)(double); 101c143c55718342519db5398e41dda31422cf16c79buzbee float (*pL2f)(long); 102c143c55718342519db5398e41dda31422cf16c79buzbee double (*pL2d)(long); 1031b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee long long (*pF2l)(float); 1041b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee long long (*pD2l)(double); 105c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFadd)(float, float); 106c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFsub)(float, float); 107c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFdiv)(float, float); 108c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFmul)(float, float); 109c143c55718342519db5398e41dda31422cf16c79buzbee float (*pFmodf)(float, float); 110c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDadd)(double, double); 111c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDsub)(double, double); 112c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDdiv)(double, double); 113c143c55718342519db5398e41dda31422cf16c79buzbee double (*pDmul)(double, double); 114c143c55718342519db5398e41dda31422cf16c79buzbee double (*pFmod)(double, double); 115c143c55718342519db5398e41dda31422cf16c79buzbee int (*pIdivmod)(int, int); 116c143c55718342519db5398e41dda31422cf16c79buzbee int (*pIdiv)(int, int); 117439c4fa0db980fb19e4a585723a64a3461e4c278buzbee long long (*pLmul)(long long, long long); 118c143c55718342519db5398e41dda31422cf16c79buzbee long long (*pLdivmod)(long long, long long); 1194a510d8750d50b77353d0a5a891d1b9b3a48ecd5Ian Rogers void (*pCheckSuspendFromCode)(Thread*); // Stub that is called when the suspend count is non-zero 1204a510d8750d50b77353d0a5a891d1b9b3a48ecd5Ian Rogers void (*pTestSuspendFromCode)(); // Stub that is periodically called to test the suspend count 12121d9e8323124a832a21679ca83808bc9c68ed365Ian Rogers void* (*pAllocObjectFromCode)(uint32_t, void*); 122b408de744566a5c5a80be1ba7f5c88407e816945Elliott Hughes void* (*pAllocArrayFromCode)(uint32_t, void*, int32_t); 123e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers void (*pCanPutArrayElementFromCode)(void*, void*); 124ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t); 125362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes void (*pCheckCastFromCode)(void*, void*); 126ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj); 12767375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers void (*pDeliverException)(void*); 128ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pFindInstanceFieldFromCode)(uint32_t, void*); 129ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); 130ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pFindNativeMethod)(Thread* thread); 131ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers int32_t (*pGet32Static)(uint32_t, void*); 132ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers int64_t (*pGet64Static)(uint32_t, void*); 133ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pGetObjStatic)(uint32_t, void*); 134ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers void (*pHandleFillArrayDataFromCode)(void*, void*); 135ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pInitializeStaticStorage)(uint32_t, void*); 136362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes uint32_t (*pInstanceofNonTrivialFromCode)(const Class*, const Class*); 137ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void (*pInvokeInterfaceTrampoline)(uint32_t, void*); 1381b4c85959b3d9a4a33bc2160c46c1bbde67350c7buzbee Class* (*pInitializeTypeFromCode)(uint32_t, Method*); 139ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void (*pLockObjectFromCode)(void*); 1406fd03fb67e4628689f0abf34edeacc0e35b6295eBrian Carlstrom void (*pObjectInit)(void*); 141561227c80077bbb4147f778043f1a836af6b9248buzbee void (*pResolveMethodFromCode)(Method*, uint32_t); 142aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom void* (*pResolveStringFromCode)(void*, uint32_t); 143ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers int (*pSet32Static)(uint32_t, void*, int32_t); 144ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers int (*pSet64Static)(uint32_t, void*, int64_t); 145ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers int (*pSetObjStatic)(uint32_t, void*, void*); 146932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers void (*pThrowStackOverflowFromCode)(void*); 1475ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowNullPointerFromCode)(); 1485ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowArrayBoundsFromCode)(int32_t, int32_t); 1495ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowDivZeroFromCode)(); 1505ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowVerificationErrorFromCode)(int32_t, int32_t); 1515ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowNegArraySizeFromCode)(int32_t); 1525ade1d255ef1b5022321ac20493208703b34d2b1buzbee void (*pThrowNoSuchMethodFromCode)(int32_t); 153ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp); 154ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void (*pUnlockObjectFromCode)(void*); 155ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers void* (*pUnresolvedDirectMethodTrampolineFromCode)(int32_t, void*, Thread*, 156ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers Runtime::TrampolineType); 157c143c55718342519db5398e41dda31422cf16c79buzbee 1589b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao class StackVisitor { 1599b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 1600cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers virtual ~StackVisitor() {} 161bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers virtual void VisitFrame(const Frame& frame, uintptr_t pc) = 0; 1629b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao }; 1639b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 16461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread. 165d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes static void Create(Object* peer, size_t stack_size); 16661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 16761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread from the calling thread. 168dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon); 169b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 170caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom // Reset internal state of child thread after fork. 171caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitAfterFork(); 172caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 173b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static Thread* Current() { 174d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro void* thread = pthread_getspecific(Thread::pthread_key_self_); 175d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro return reinterpret_cast<Thread*>(thread); 1760e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1770e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 17801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes static Thread* FromManagedThread(JNIEnv* env, jobject thread); 1798e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes static uint32_t LockOwnerFromThreadLock(Object* thread_lock); 1808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 181a09576416788b916095739e43a16917e7948f3a4Elliott Hughes void Dump(std::ostream& os) const; 182a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 1830cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers State GetState() const { 1840cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return state_; 1850cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 1860cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 1878d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes State SetState(State new_state); 1888d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 189038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes bool IsDaemon(); 190038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes 1918d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes void WaitUntilSuspended(); 1920cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 1935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes bool HoldsLock(Object*); 1945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes /* 1968daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Changes the priority of this thread to match that of the java.lang.Thread object. 1978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 1988daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * We map a priority value from 1-10 to Linux "nice" values, where lower 1998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * numbers indicate higher priority. 2008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 2018daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes void SetNativePriority(int newPriority); 2028daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2038daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes /* 2048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Returns the thread priority for the current thread by querying the system. 2058daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * This is useful when attaching a thread through JNI. 2068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 2078daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Returns a value from 1 to 10 (compatible with java.lang.Thread values). 2088daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 2098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes static int GetNativePriority(); 2108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers bool CanAccessDirectReferences() const { 212caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom#ifdef MOVING_GARBAGE_COLLECTOR 213a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes // TODO: when we have a moving collector, we'll need: return state_ == kRunnable; 214caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom#endif 215a59d1793b89d0fd62c7544c94da4b6e5dac95ad5Elliott Hughes return true; 2160cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2170cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 218dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t GetThinLockId() const { 219dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return thin_lock_id_; 220b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 221b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 222d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t GetTid() const { 223d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes return tid_; 224d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 225e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 226fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes // Returns the java.lang.Thread's name, or NULL. 227fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes String* GetName() const; 228fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 229fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes // Returns the current method's declaring class' source file and the current line number. 230fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes void GetCurrentLocation(const char*& source_file, uint32_t& line_number) const; 231fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 232d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes Object* GetPeer() const { 2338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return peer_; 2348daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 2358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes RuntimeStats* GetStats() { 2379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return &stats_; 2389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2400cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // Returns the Method* for the current method. 2410cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // This is used by the JNI implementation for logging and diagnostic purposes. 2429fd66f5bb6a514147a53d57b419d18ecc7937122Elliott Hughes const Method* GetCurrentMethod() const; 2430cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool IsExceptionPending() const { 245b20a554613609dc372073d2ebd9fbc3925a429f5Elliott Hughes return exception_ != NULL; 2460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 248e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes Throwable* GetException() const { 2490cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 2500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro return exception_; 2510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2530cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void SetException(Throwable* new_exception) { 2540cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 2550cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers CHECK(new_exception != NULL); 2560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: CHECK(exception_ == NULL); 2570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = new_exception; // TODO 2580cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2590cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers 2600cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers void ClearException() { 2610cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers exception_ = NULL; 262a09576416788b916095739e43a16917e7948f3a4Elliott Hughes } 263a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 264bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Find catch block and perform long jump to appropriate exception handle 265ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers void DeliverException(); 266bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 267bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Context* GetLongJumpContext(); 268bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 2691a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame GetTopOfStack() const { 2701a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao return top_of_managed_stack_; 2711a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 2721a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 2731a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // TODO: this is here for testing, remove when we have exception unit tests 2741a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao // that use the real stack 275bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers void SetTopOfStack(void* stack, uintptr_t pc) { 2760cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack)); 277bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers top_of_managed_stack_pc_ = pc; 2780e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 2790e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 280bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers void SetTopOfStackPC(uintptr_t pc) { 281bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers top_of_managed_stack_pc_ = pc; 282bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 283bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 2845cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes // 'msg' may be NULL. 2855cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes void ThrowNewException(const char* exception_class_descriptor, const char* msg); 2865cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes 2875cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes void ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...) 288362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes __attribute__((format(printf, 3, 4))); 289a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes 2904a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes void ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap); 2914a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes 2922ced6a534157d5d963693346904389c19775d2daElliott Hughes // OutOfMemoryError is special, because we need to pre-allocate an instance. 2932ced6a534157d5d963693346904389c19775d2daElliott Hughes void ThrowOutOfMemoryError(const char* msg); 294418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes void ThrowOutOfMemoryError(Class* c, size_t byte_count); 29579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 2961a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao Frame FindExceptionHandler(void* throw_pc, void** handler_pc); 2971a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 2981a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* FindExceptionHandlerInMethod(const Method* method, 2991a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao void* throw_pc, 3001a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao const DexFile& dex_file, 3011a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao ClassLinker* class_linker); 302c143c55718342519db5398e41dda31422cf16c79buzbee 303b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void SetName(const char* name); 304b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 305be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static void Startup(); 306038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes static void FinishStartup(); 307c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes static void Shutdown(); 308b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 309b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // JNI methods 31069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes JNIEnvExt* GetJniEnv() const { 311b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return jni_env_; 312b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 313b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 314408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Number of references allocated in SIRTs on this thread 315408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers size_t NumSirtReferences(); 316a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 317408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Is the given obj in this thread's stack indirect reference table? 318408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers bool SirtContains(jobject obj); 319408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 3208dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg); 3218dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao 322408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Convert a jobject into a Object* 323408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object* DecodeJObject(jobject obj); 324b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 3258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Implements java.lang.Thread.interrupted. 3268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool Interrupted() { 32785d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 3288daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool interrupted = interrupted_; 3298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes interrupted_ = false; 3308daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return interrupted; 3318daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 3328daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 3338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Implements java.lang.Thread.isInterrupted. 3348daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes bool IsInterrupted() { 33585d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 3368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes return interrupted_; 3378daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 3388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 3395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Interrupt() { 34085d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 3415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (interrupted_) { 3425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 3435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes interrupted_ = true; 3455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes NotifyLocked(); 3465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void Notify() { 34985d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*wait_mutex_); 3505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes NotifyLocked(); 3515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3536de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // Linked list recording transitions from native to managed code 354b04f69f90d2594092bec5b294bbe7329d295bd66Ian Rogers void PushNativeToManagedRecord(NativeToManagedRecord* record); 355b04f69f90d2594092bec5b294bbe7329d295bd66Ian Rogers void PopNativeToManagedRecord(const NativeToManagedRecord& record); 3566de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers 357bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom const ClassLoader* GetClassLoaderOverride() { 3580cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // TODO: need to place the class_loader_override_ in a handle 3590cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // DCHECK(CanAccessDirectReferences()); 360c143c55718342519db5398e41dda31422cf16c79buzbee return class_loader_override_; 361c143c55718342519db5398e41dda31422cf16c79buzbee } 362c143c55718342519db5398e41dda31422cf16c79buzbee 363bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom void SetClassLoaderOverride(const ClassLoader* class_loader_override) { 364c143c55718342519db5398e41dda31422cf16c79buzbee class_loader_override_ = class_loader_override; 365c143c55718342519db5398e41dda31422cf16c79buzbee } 366c143c55718342519db5398e41dda31422cf16c79buzbee 367aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Create the internal representation of a stack trace, that is more time 368aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // and space efficient to compute than the StackTraceElement[] 36901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobject CreateInternalStackTrace(JNIEnv* env) const; 37001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 37101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Convert an internal stack trace representation (returned by CreateInternalStackTrace) to a 37201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // StackTraceElement[]. If output_array is NULL, a new array is created, otherwise as many 37301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // frames as will fit are written into the given array. If stack_depth is non-NULL, it's updated 37401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // with the number of valid frames in the returned array. 37501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal, 37601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobjectArray output_array = NULL, int* stack_depth = NULL); 37755df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 378d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers void VisitRoots(Heap::RootVisitor* visitor, void* arg); 379410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 380be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // 381be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // Offsets of various members of native Thread class, used by compiled code. 382be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes // 383be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 384be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset SelfOffset() { 385be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, self_)); 386be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 387be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 388be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset ExceptionOffset() { 389be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_)); 390be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 391be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 39254e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes static ThreadOffset ThinLockIdOffset() { 393be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_)); 394be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 395be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 396be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset CardTableOffset() { 397be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_)); 398be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 399be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 400be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset SuspendCountOffset() { 401be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_)); 402be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 403be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 404be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset StateOffset() { 40593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes return ThreadOffset(OFFSETOF_VOLATILE_MEMBER(Thread, state_)); 406be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 407be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 408932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Size of stack less any space reserved for stack overflow 409932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers size_t GetStackSize() { 410932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers return stack_size_ - (stack_end_ - stack_base_); 411932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers } 412932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 413932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set the stack end to that to be used during a stack overflow 414932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers void SetStackEndForStackOverflow() { 415932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // During stack overflow we allow use of the full stack 4163b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes if (stack_end_ == stack_base_) { 4173b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes DumpStack(std::cerr); 4183b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes LOG(FATAL) << "Need to increase kStackOverflowReservedBytes (currently " 4193b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes << kStackOverflowReservedBytes << ")"; 4203b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes } 4213b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes 422932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers stack_end_ = stack_base_; 423932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers } 424932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 425932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set the stack end to that to be used during regular execution 426932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers void ResetDefaultStackEnd() { 427932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Our stacks grow down, so we want stack_end_ to be near there, but reserving enough room 428932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // to throw a StackOverflowError. 429932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers stack_end_ = stack_base_ + kStackOverflowReservedBytes; 430932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers } 431932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 432449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes static ThreadOffset StackEndOffset() { 433449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, stack_end_)); 434be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 435be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 436be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset JniEnvOffset() { 437be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 438be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 439be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 440be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset TopOfManagedStackOffset() { 441be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) + 442be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes OFFSETOF_MEMBER(Frame, sp_)); 443be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 444be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 445bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers static ThreadOffset TopOfManagedStackPcOffset() { 446bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_)); 447bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 448bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 44940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom void PushSirt(StackIndirectReferenceTable* sirt); 45040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom StackIndirectReferenceTable* PopSirt(); 45140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom 452be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static ThreadOffset TopSirtOffset() { 453be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); 454be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 455be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 4569407c60800c95902fba0b3c3265520d47c1e7052Shih-wei Liao void WalkStack(StackVisitor* visitor) const; 4579407c60800c95902fba0b3c3265520d47c1e7052Shih-wei Liao 4580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 459dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes Thread(); 460c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes ~Thread(); 46102b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes friend class ThreadList; // For ~Thread. 4620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 4635fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes void CreatePeer(const char* name, bool as_daemon); 4645fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes friend class Runtime; // For CreatePeer. 4655fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 466d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void DumpState(std::ostream& os) const; 467d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes void DumpStack(std::ostream& os) const; 468d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 469accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Out-of-line conveniences for debugging in gdb. 470498508c1187dc07d3eae5476784cde20f5224d93Elliott Hughes static Thread* CurrentFromGdb(); // Like Thread::Current. 471accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes void DumpFromGdb() const; // Like Thread::Dump(std::cerr). 472accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 47393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes void Attach(const Runtime* runtime); 47493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes static void* CreateCallback(void* arg); 47593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 476accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes void HandleUncaughtExceptions(); 477accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 478b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void InitCpu(); 4793ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee void InitFunctionPointers(); 480caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitTid(); 481caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom void InitPthreadKeySelf(); 482be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes void InitStackHwm(); 483be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 4845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes void NotifyLocked() { 4855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wait_monitor_ != NULL) { 48685d1545e985ac689db4bad7849880e843707c862Elliott Hughes wait_cond_->Signal(); 4875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 490be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes static void ThreadExitCallback(void* arg); 491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 49267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers void WalkStackUntilUpCall(StackVisitor* visitor, bool include_upcall) const; 493bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 494dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Thin lock thread id. This is a small integer used by the thin lock implementation. 495dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // This is not to be confused with the native thread's tid, nor is it the value returned 496dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One 497dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // important difference between this id and the ids visible to managed code is that these 498dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // ones get reused (to ensure that they fit in the number of bits available). 499dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes uint32_t thin_lock_id_; 500b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 501d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // System thread id. 502d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes pid_t tid_; 503d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 504dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes // Our managed peer (an instance of java.lang.Thread). 505d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes Object* peer_; 5068daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 5078e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // The top_of_managed_stack_ and top_of_managed_stack_pc_ fields are accessed from 5088e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // compiled code, so we keep them early in the structure to (a) avoid having to keep 5098e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // fixing the assembler offsets and (b) improve the chances that these will still be aligned. 5108e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 5118e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // Top of the managed stack, written out prior to the state transition from 51268e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes // kRunnable to kNative. Uses include giving the starting point for scanning 5138e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // a managed stack when a thread is in native code. 5148e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Frame top_of_managed_stack_; 5158e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // PC corresponding to the call out of the top_of_managed_stack_ frame 5168e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes uintptr_t top_of_managed_stack_pc_; 5178e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 5188daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Guards the 'interrupted_' and 'wait_monitor_' members. 51985d1545e985ac689db4bad7849880e843707c862Elliott Hughes mutable Mutex* wait_mutex_; 52085d1545e985ac689db4bad7849880e843707c862Elliott Hughes ConditionVariable* wait_cond_; 5218daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Pointer to the monitor lock we're currently waiting on (or NULL), guarded by wait_mutex_. 5228daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes Monitor* wait_monitor_; 5238daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Thread "interrupted" status; stays raised until queried or thrown, guarded by wait_mutex_. 5248e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes uint32_t interrupted_; 5255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The next thread in the wait set this thread is part of. 5265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* wait_next_; 5278e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // If we're blocked in MonitorEnter, this is the object we're trying to lock. 5288e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Object* monitor_enter_object_; 5295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 5305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes friend class Monitor; 531dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 5329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes RuntimeStats stats_; 5339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 534c143c55718342519db5398e41dda31422cf16c79buzbee // FIXME: placeholder for the gc cardTable 535c143c55718342519db5398e41dda31422cf16c79buzbee uint32_t card_table_; 536c143c55718342519db5398e41dda31422cf16c79buzbee 537449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes // The end of this thread's stack. This is the lowest safely-addressable address on the stack. 538449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes // We leave extra space so there's room for the code that throws StackOverflowError. 539449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes byte* stack_end_; 540be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 541932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Size of the stack 542932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers size_t stack_size_; 543932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 544932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // The "lowest addressable byte" of the stack 545932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers byte* stack_base_; 546932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 5476de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // A linked list (of stack allocated records) recording transitions from 5486de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers // native to managed code. 5496de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers NativeToManagedRecord* native_to_managed_record_; 5506de0860c491d390b7a53be436519ef2d9234c4c9Ian Rogers 551408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Top of linked list of stack indirect reference tables or NULL for none 552408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers StackIndirectReferenceTable* top_sirt_; 553b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 554b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Every thread may have an associated JNI environment 55569f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes JNIEnvExt* jni_env_; 556b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 55793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes volatile State state_; 558b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 55969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Initialized to "this". On certain architectures (such as x86) reading 56069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // off of Thread::Current is easy but getting the address of Thread::Current 56169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // is hard. This field can be read off of Thread::Current to give the address. 56269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Thread* self_; 56369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 56469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Runtime* runtime_; 56569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 56669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // The pending exception or NULL. 567e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes Throwable* exception_; 5680e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 56945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // A non-zero value is used to tell the current thread to enter a safe point 57045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers // at the next poll. 57145a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers int suspend_count_; 57245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 573edcc09c737b00462881f147602656739d029571eElliott Hughes // Needed to get the right ClassLoader in JNI_OnLoad, but also 574edcc09c737b00462881f147602656739d029571eElliott Hughes // useful for testing. 575bffb15585b8fd43d3ca534ddbb85e7f591595951Brian Carlstrom const ClassLoader* class_loader_override_; 576c143c55718342519db5398e41dda31422cf16c79buzbee 577bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Thread local, lazily allocated, long jump context. Used to deliver exceptions. 57885d1545e985ac689db4bad7849880e843707c862Elliott Hughes Context* long_jump_context_; 579bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 580418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes // A boolean telling us whether we're recursively throwing OOME. 581726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes uint32_t throwing_OutOfMemoryError_; 582726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes 583726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes Throwable* pre_allocated_OutOfMemoryError_; 584418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes 58569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // TLS key used to retrieve the VM thread object. 586b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static pthread_key_t pthread_key_self_; 587b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 5880e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Thread); 5890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 590bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 591330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread); 592b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state); 5930e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 594ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesclass ScopedThreadStateChange { 595ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes public: 596ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) { 597ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes old_thread_state_ = thread_->SetState(new_state); 598ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes } 599ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 600ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes ~ScopedThreadStateChange() { 601ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes thread_->SetState(old_thread_state_); 602ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes } 603ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 604ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes private: 605ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread* thread_; 606ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread::State old_thread_state_; 607ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange); 608ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes}; 609ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 6100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 6110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 6120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_THREAD_H_ 613