thread.h revision dcc247493fd8fb243e335c3ec08e5e625896a47c
1// Copyright 2011 Google Inc. All Rights Reserved. 2 3#ifndef ART_SRC_THREAD_H_ 4#define ART_SRC_THREAD_H_ 5 6#include <pthread.h> 7 8#include <iosfwd> 9#include <list> 10 11#include "dex_file.h" 12#include "globals.h" 13#include "jni_internal.h" 14#include "logging.h" 15#include "macros.h" 16#include "mem_map.h" 17#include "offsets.h" 18 19namespace art { 20 21class Array; 22class Class; 23class ClassLinker; 24class ClassLoader; 25class Method; 26class Object; 27class Runtime; 28class Thread; 29class ThreadList; 30class Throwable; 31class StackTraceElement; 32class StaticStorageBase; 33 34template<class T> class ObjectArray; 35template<class T> class PrimitiveArray; 36typedef PrimitiveArray<int32_t> IntArray; 37 38class Mutex { 39 public: 40 virtual ~Mutex() {} 41 42 void Lock(); 43 44 bool TryLock(); 45 46 void Unlock(); 47 48 const char* GetName() { return name_; } 49 50 Thread* GetOwner() { return owner_; } 51 52 static Mutex* Create(const char* name); 53 54 // TODO: only needed because we lack a condition variable abstraction. 55 pthread_mutex_t* GetImpl() { return &lock_impl_; } 56 57 private: 58 explicit Mutex(const char* name) : name_(name), owner_(NULL) {} 59 60 void SetOwner(Thread* thread) { owner_ = thread; } 61 62 const char* name_; 63 64 Thread* owner_; 65 66 pthread_mutex_t lock_impl_; 67 68 DISALLOW_COPY_AND_ASSIGN(Mutex); 69}; 70 71class MutexLock { 72 public: 73 explicit MutexLock(Mutex *mu) : mu_(mu) { 74 mu_->Lock(); 75 } 76 ~MutexLock() { mu_->Unlock(); } 77 private: 78 Mutex* const mu_; 79 DISALLOW_COPY_AND_ASSIGN(MutexLock); 80}; 81 82// Stack allocated indirect reference table, allocated within the bridge frame 83// between managed and native code. 84class StackIndirectReferenceTable { 85 public: 86 // Number of references contained within this SIRT 87 size_t NumberOfReferences() { 88 return number_of_references_; 89 } 90 91 // Link to previous SIRT or NULL 92 StackIndirectReferenceTable* Link() { 93 return link_; 94 } 95 96 Object** References() { 97 return references_; 98 } 99 100 // Offset of length within SIRT, used by generated code 101 static size_t NumberOfReferencesOffset() { 102 return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_); 103 } 104 105 // Offset of link within SIRT, used by generated code 106 static size_t LinkOffset() { 107 return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_); 108 } 109 110 private: 111 StackIndirectReferenceTable() {} 112 113 size_t number_of_references_; 114 StackIndirectReferenceTable* link_; 115 116 // Fake array, really allocated and filled in by jni_compiler. 117 Object* references_[0]; 118 119 DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable); 120}; 121 122struct NativeToManagedRecord { 123 NativeToManagedRecord* link; 124 void* last_top_of_managed_stack; 125}; 126 127// Iterator over managed frames up to the first native-to-managed transition 128class Frame { 129 public: 130 Frame() : sp_(NULL) {} 131 132 Method* GetMethod() const { 133 return (sp_ != NULL) ? *sp_ : NULL; 134 } 135 136 bool HasNext() const { 137 return NextMethod() != NULL; 138 } 139 140 void Next(); 141 142 uintptr_t GetPC() const; 143 144 Method** GetSP() const { 145 return sp_; 146 } 147 148 // TODO: this is here for testing, remove when we have exception unit tests 149 // that use the real stack 150 void SetSP(Method** sp) { 151 sp_ = sp; 152 } 153 154 private: 155 Method* NextMethod() const; 156 157 friend class Thread; 158 159 Method** sp_; 160}; 161 162class Thread { 163 public: 164 enum State { 165 kUnknown = -1, 166 kNew, 167 kRunnable, 168 kBlocked, 169 kWaiting, 170 kTimedWaiting, 171 kNative, 172 kTerminated, 173 }; 174 175 176 static const size_t kDefaultStackSize = 64 * KB; 177 178 // Runtime support function pointers 179 void (*pDebugMe)(Method*, uint32_t); 180 void* (*pMemcpy)(void*, const void*, size_t); 181 uint64_t (*pShlLong)(uint64_t, uint32_t); 182 uint64_t (*pShrLong)(uint64_t, uint32_t); 183 uint64_t (*pUshrLong)(uint64_t, uint32_t); 184 float (*pI2f)(int); 185 int (*pF2iz)(float); 186 float (*pD2f)(double); 187 double (*pF2d)(float); 188 double (*pI2d)(int); 189 int (*pD2iz)(double); 190 float (*pL2f)(long); 191 double (*pL2d)(long); 192 long long (*pF2l)(float); 193 long long (*pD2l)(double); 194 float (*pFadd)(float, float); 195 float (*pFsub)(float, float); 196 float (*pFdiv)(float, float); 197 float (*pFmul)(float, float); 198 float (*pFmodf)(float, float); 199 double (*pDadd)(double, double); 200 double (*pDsub)(double, double); 201 double (*pDdiv)(double, double); 202 double (*pDmul)(double, double); 203 double (*pFmod)(double, double); 204 int (*pIdivmod)(int, int); 205 int (*pIdiv)(int, int); 206 long long (*pLmul)(long long, long long); 207 long long (*pLdivmod)(long long, long long); 208 Array* (*pAllocFromCode)(uint32_t, Method*, int32_t); 209 Array* (*pCheckAndAllocFromCode)(uint32_t, Method*, int32_t); 210 Object* (*pAllocObjectFromCode)(uint32_t, Method*); 211 uint32_t (*pGet32Static)(uint32_t, const Method*); 212 void (*pSet32Static)(uint32_t, const Method*, uint32_t); 213 uint64_t (*pGet64Static)(uint32_t, const Method*); 214 void (*pSet64Static)(uint32_t, const Method*, uint64_t); 215 Object* (*pGetObjStatic)(uint32_t, const Method*); 216 void (*pSetObjStatic)(uint32_t, const Method*, Object*); 217 void (*pCanPutArrayElementFromCode)(const Class*, const Class*); 218 int (*pInstanceofNonTrivialFromCode) (const Class*, const Class*); 219 Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); 220 bool (*pUnlockObjectFromCode)(Thread*, Object*); 221 void (*pLockObjectFromCode)(Thread*, Object*); 222 void (*pThrowException)(Thread*, Throwable*); 223 void (*pHandleFillArrayDataFromCode)(Array*, const uint16_t*); 224 Class* (*pInitializeTypeFromCode)(uint32_t, Method*); 225 void (*pResolveMethodFromCode)(Method*, uint32_t); 226 void (*pInvokeInterfaceTrampoline)(void*, void*, void*, void*); 227 StaticStorageBase* (*pInitializeStaticStorage)(uint32_t, const Method*); 228 229 class StackVisitor { 230 public: 231 virtual ~StackVisitor() {} 232 virtual bool VisitFrame(const Frame& frame) = 0; 233 }; 234 235 // Creates a new thread. 236 static Thread* Create(const Runtime* runtime); 237 238 // Creates a new thread from the calling thread. 239 static Thread* Attach(const Runtime* runtime, const char* name, bool as_daemon); 240 241 static Thread* Current() { 242 void* thread = pthread_getspecific(Thread::pthread_key_self_); 243 return reinterpret_cast<Thread*>(thread); 244 } 245 246 void Dump(std::ostream& os) const; 247 248 State GetState() const { 249 return state_; 250 } 251 252 State SetState(State new_state) { 253 State old_state = state_; 254 state_ = new_state; 255 return old_state; 256 } 257 258 bool CanAccessDirectReferences() const { 259 // TODO: when we have a moving collector, we'll need: return state_ == kRunnable; 260 return true; 261 } 262 263 uint32_t GetThinLockId() const { 264 return thin_lock_id_; 265 } 266 267 pid_t GetTid() const { 268 return tid_; 269 } 270 271 pthread_t GetImpl() const { 272 return handle_; 273 } 274 275 // Returns the Method* for the current method. 276 // This is used by the JNI implementation for logging and diagnostic purposes. 277 const Method* GetCurrentMethod() const { 278 return top_of_managed_stack_.GetMethod(); 279 } 280 281 bool IsExceptionPending() const { 282 return exception_ != NULL; 283 } 284 285 Throwable* GetException() const { 286 DCHECK(CanAccessDirectReferences()); 287 return exception_; 288 } 289 290 void SetException(Throwable* new_exception) { 291 DCHECK(CanAccessDirectReferences()); 292 CHECK(new_exception != NULL); 293 // TODO: CHECK(exception_ == NULL); 294 exception_ = new_exception; // TODO 295 } 296 297 void ClearException() { 298 exception_ = NULL; 299 } 300 301 Frame GetTopOfStack() const { 302 return top_of_managed_stack_; 303 } 304 305 // TODO: this is here for testing, remove when we have exception unit tests 306 // that use the real stack 307 void SetTopOfStack(void* stack) { 308 top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(stack)); 309 } 310 311 void ThrowNewException(const char* exception_class_descriptor, const char* fmt, ...) 312 __attribute__ ((format(printf, 3, 4))); 313 314 // This exception is special, because we need to pre-allocate an instance. 315 void ThrowOutOfMemoryError(); 316 317 Frame FindExceptionHandler(void* throw_pc, void** handler_pc); 318 319 void* FindExceptionHandlerInMethod(const Method* method, 320 void* throw_pc, 321 const DexFile& dex_file, 322 ClassLinker* class_linker); 323 static ThreadOffset SelfOffset() { 324 return ThreadOffset(OFFSETOF_MEMBER(Thread, self_)); 325 } 326 327 // Offset of exception_ within Thread, used by generated code 328 static ThreadOffset ExceptionOffset() { 329 return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_)); 330 } 331 332 // Offset of thin_lock_id_ within Thread, used by generated code 333 static ThreadOffset IdOffset() { 334 return ThreadOffset(OFFSETOF_MEMBER(Thread, thin_lock_id_)); 335 } 336 337 // Offset of card_table within Thread, used by generated code 338 static ThreadOffset CardTableOffset() { 339 return ThreadOffset(OFFSETOF_MEMBER(Thread, card_table_)); 340 } 341 342 void SetName(const char* name); 343 344 void Suspend(); 345 346 bool IsSuspended(); 347 348 void Resume(); 349 350 static bool Startup(); 351 static void Shutdown(); 352 353 static ThreadOffset SuspendCountOffset() { 354 return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_)); 355 } 356 357 // Offset of state within Thread, used by generated code 358 static ThreadOffset StateOffset() { 359 return ThreadOffset(OFFSETOF_MEMBER(Thread, state_)); 360 } 361 362 // JNI methods 363 JNIEnvExt* GetJniEnv() const { 364 return jni_env_; 365 } 366 367 // Offset of JNI environment within Thread, used by generated code 368 static ThreadOffset JniEnvOffset() { 369 return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 370 } 371 372 // Offset of top of managed stack address, used by generated code 373 static ThreadOffset TopOfManagedStackOffset() { 374 return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_) + 375 OFFSETOF_MEMBER(Frame, sp_)); 376 } 377 378 // Offset of top stack indirect reference table within Thread, used by 379 // generated code 380 static ThreadOffset TopSirtOffset() { 381 return ThreadOffset(OFFSETOF_MEMBER(Thread, top_sirt_)); 382 } 383 384 // Number of references allocated in SIRTs on this thread 385 size_t NumSirtReferences(); 386 387 // Is the given obj in this thread's stack indirect reference table? 388 bool SirtContains(jobject obj); 389 390 // Convert a jobject into a Object* 391 Object* DecodeJObject(jobject obj); 392 393 // Offset of exception_entry_point_ within Thread, used by generated code 394 static ThreadOffset ExceptionEntryPointOffset() { 395 return ThreadOffset(OFFSETOF_MEMBER(Thread, exception_entry_point_)); 396 } 397 398 void RegisterExceptionEntryPoint(void (*handler)(Method**)) { 399 exception_entry_point_ = handler; 400 } 401 402 // Offset of suspend_count_entry_point_ within Thread, used by generated code 403 static ThreadOffset SuspendCountEntryPointOffset() { 404 return ThreadOffset(OFFSETOF_MEMBER(Thread, suspend_count_entry_point_)); 405 } 406 407 void RegisterSuspendCountEntryPoint(void (*handler)(Method**)) { 408 suspend_count_entry_point_ = handler; 409 } 410 411 // Increasing the suspend count, will cause the thread to run to safepoint 412 void IncrementSuspendCount() { suspend_count_++; } 413 void DecrementSuspendCount() { suspend_count_--; } 414 415 // Linked list recording transitions from native to managed code 416 void PushNativeToManagedRecord(NativeToManagedRecord* record) { 417 record->last_top_of_managed_stack = reinterpret_cast<void*>(top_of_managed_stack_.GetSP()); 418 record->link = native_to_managed_record_; 419 native_to_managed_record_ = record; 420 top_of_managed_stack_.SetSP(NULL); 421 } 422 void PopNativeToManagedRecord(const NativeToManagedRecord& record) { 423 native_to_managed_record_ = record.link; 424 top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(record.last_top_of_managed_stack)); 425 } 426 427 const ClassLoader* GetClassLoaderOverride() { 428 // TODO: need to place the class_loader_override_ in a handle 429 // DCHECK(CanAccessDirectReferences()); 430 return class_loader_override_; 431 } 432 433 void SetClassLoaderOverride(const ClassLoader* class_loader_override) { 434 class_loader_override_ = class_loader_override; 435 } 436 437 // Allocate stack trace 438 ObjectArray<StackTraceElement>* AllocStackTrace(); 439 440 void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 441 442 private: 443 Thread(); 444 ~Thread(); 445 friend class Runtime; // For ~Thread. 446 447 void DumpState(std::ostream& os) const; 448 void DumpStack(std::ostream& os) const; 449 450 void InitCpu(); 451 void InitFunctionPointers(); 452 453 void WalkStack(StackVisitor* visitor); 454 455 // Thin lock thread id. This is a small integer used by the thin lock implementation. 456 // This is not to be confused with the native thread's tid, nor is it the value returned 457 // by java.lang.Thread.getId --- this is a distinct value, used only for locking. One 458 // important difference between this id and the ids visible to managed code is that these 459 // ones get reused (to ensure that they fit in the number of bits available). 460 uint32_t thin_lock_id_; 461 462 // System thread id. 463 pid_t tid_; 464 465 // Native thread handle. 466 pthread_t handle_; 467 468 bool is_daemon_; 469 470 // Our managed peer (an instance of java.lang.Thread). 471 Object* peer_; 472 473 // FIXME: placeholder for the gc cardTable 474 uint32_t card_table_; 475 476 // Top of the managed stack, written out prior to the state transition from 477 // kRunnable to kNative. Uses include to give the starting point for scanning 478 // a managed stack when a thread is in native code. 479 Frame top_of_managed_stack_; 480 481 // A linked list (of stack allocated records) recording transitions from 482 // native to managed code. 483 NativeToManagedRecord* native_to_managed_record_; 484 485 // Top of linked list of stack indirect reference tables or NULL for none 486 StackIndirectReferenceTable* top_sirt_; 487 488 // Every thread may have an associated JNI environment 489 JNIEnvExt* jni_env_; 490 491 State state_; 492 493 // Initialized to "this". On certain architectures (such as x86) reading 494 // off of Thread::Current is easy but getting the address of Thread::Current 495 // is hard. This field can be read off of Thread::Current to give the address. 496 Thread* self_; 497 498 Runtime* runtime_; 499 500 // The pending exception or NULL. 501 Throwable* exception_; 502 503 // A non-zero value is used to tell the current thread to enter a safe point 504 // at the next poll. 505 int suspend_count_; 506 507 // Needed to get the right ClassLoader in JNI_OnLoad, but also 508 // useful for testing. 509 const ClassLoader* class_loader_override_; 510 511 // TLS key used to retrieve the VM thread object. 512 static pthread_key_t pthread_key_self_; 513 514 // Entry point called when exception_ is set 515 void (*exception_entry_point_)(Method** frame); 516 517 // Entry point called when suspend_count_ is non-zero 518 void (*suspend_count_entry_point_)(Method** frame); 519 520 DISALLOW_COPY_AND_ASSIGN(Thread); 521}; 522std::ostream& operator<<(std::ostream& os, const Thread& thread); 523std::ostream& operator<<(std::ostream& os, const Thread::State& state); 524 525class ThreadList { 526 public: 527 static const int kMaxId = 0xFFFF; 528 static const int kInvalidId = 0; 529 static const int kMainId = 1; 530 531 static ThreadList* Create(); 532 533 ~ThreadList(); 534 535 void Dump(std::ostream& os); 536 537 void Register(Thread* thread); 538 539 void Unregister(Thread* thread); 540 541 bool Contains(Thread* thread); 542 543 void Lock() { 544 lock_->Lock(); 545 } 546 547 void Unlock() { 548 lock_->Unlock(); 549 }; 550 551 void VisitRoots(Heap::RootVisitor* visitor, void* arg) const; 552 553 private: 554 ThreadList(); 555 556 std::list<Thread*> list_; 557 558 Mutex* lock_; 559 560 DISALLOW_COPY_AND_ASSIGN(ThreadList); 561}; 562 563class ThreadListLock { 564 public: 565 ThreadListLock(ThreadList* thread_list, Thread* current_thread) 566 : thread_list_(thread_list) { 567 if (current_thread == NULL) { // try to get it from TLS 568 current_thread = Thread::Current(); 569 } 570 Thread::State old_state; 571 if (current_thread != NULL) { 572 old_state = current_thread->SetState(Thread::kWaiting); // TODO: VMWAIT 573 } else { 574 // happens during VM shutdown 575 old_state = Thread::kUnknown; // TODO: something else 576 } 577 thread_list_->Lock(); 578 if (current_thread != NULL) { 579 current_thread->SetState(old_state); 580 } 581 } 582 583 ~ThreadListLock() { 584 thread_list_->Unlock(); 585 } 586 587 private: 588 ThreadList* thread_list_; 589 590 DISALLOW_COPY_AND_ASSIGN(ThreadListLock); 591}; 592 593class ScopedThreadStateChange { 594 public: 595 ScopedThreadStateChange(Thread* thread, Thread::State new_state) : thread_(thread) { 596 old_thread_state_ = thread_->SetState(new_state); 597 } 598 599 ~ScopedThreadStateChange() { 600 thread_->SetState(old_thread_state_); 601 } 602 603 private: 604 Thread* thread_; 605 Thread::State old_thread_state_; 606 DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange); 607}; 608 609} // namespace art 610 611#endif // ART_SRC_THREAD_H_ 612