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