thread.cc revision 365c10235438607541fa2259a5fec48061b90bd8
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 */ 16b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 18b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 198d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes#include <dynamic_annotations.h> 20b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <pthread.h> 212acf36d8cfeb5ddb293904148aa70f25ef6d8845Elliott Hughes#include <signal.h> 22dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom#include <sys/resource.h> 23dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom#include <sys/time.h> 24a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 25b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <algorithm> 26dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes#include <bitset> 27eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include <cerrno> 28a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iostream> 29b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <list> 30b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 31a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes#include "class_linker.h" 32df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom#include "class_loader.h" 3346e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes#include "debugger.h" 34408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers#include "heap.h" 35c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes#include "jni_internal.h" 368e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes#include "monitor.h" 3757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers#include "oat/runtime/context.h" 38a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes#include "object.h" 396d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 409a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson#include "reflection.h" 41578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "runtime.h" 425433072f589b61413e042eddf76e8190a048f71dbuzbee#include "runtime_support.h" 43aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers#include "scoped_jni_thread_state.h" 4446e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes#include "ScopedLocalRef.h" 4530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers#include "space.h" 4668e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h" 4768e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack_indirect_reference_table.h" 488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread_list.h" 49a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include "utils.h" 50776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/gc_map.h" 51eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h" 52b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 53b557353b22c728eecbd1c68593b482622c7782a8Carl Shapironamespace art { 54b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 55b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiropthread_key_t Thread::pthread_key_self_; 56b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 577dc5166ea740359d381097a7ab382c1dd404055fElliott Hughesstatic const char* kThreadNameDuringStartup = "<native thread without managed peer>"; 587dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes 595d76c435082332ef79a22962386fa92a0870e378Ian Rogersvoid Thread::InitCardTable() { 60b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes card_table_ = Runtime::Current()->GetHeap()->GetCardTable()->GetBiasedBegin(); 615d76c435082332ef79a22962386fa92a0870e378Ian Rogers} 625d76c435082332ef79a22962386fa92a0870e378Ian Rogers 6399250ba6a2cc72b8894dffa77c1fca5570087e3cElliott Hughes#if !defined(__APPLE__) 643ea0f42467790809fcfc9fc861605d465808090fElliott Hughesstatic void UnimplementedEntryPoint() { 653ea0f42467790809fcfc9fc861605d465808090fElliott Hughes UNIMPLEMENTED(FATAL); 663ea0f42467790809fcfc9fc861605d465808090fElliott Hughes} 6799250ba6a2cc72b8894dffa77c1fca5570087e3cElliott Hughes#endif 683ea0f42467790809fcfc9fc861605d465808090fElliott Hughes 693ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbeevoid Thread::InitFunctionPointers() { 7099250ba6a2cc72b8894dffa77c1fca5570087e3cElliott Hughes#if !defined(__APPLE__) // The Mac GCC is too old to accept this code. 713ea0f42467790809fcfc9fc861605d465808090fElliott Hughes // Insert a placeholder so we can easily tell if we call an unimplemented entry point. 723ea0f42467790809fcfc9fc861605d465808090fElliott Hughes uintptr_t* begin = reinterpret_cast<uintptr_t*>(&entrypoints_); 733ea0f42467790809fcfc9fc861605d465808090fElliott Hughes uintptr_t* end = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(begin) + sizeof(entrypoints_)); 743ea0f42467790809fcfc9fc861605d465808090fElliott Hughes for (uintptr_t* it = begin; it != end; ++it) { 753ea0f42467790809fcfc9fc861605d465808090fElliott Hughes *it = reinterpret_cast<uintptr_t>(UnimplementedEntryPoint); 763ea0f42467790809fcfc9fc861605d465808090fElliott Hughes } 7799250ba6a2cc72b8894dffa77c1fca5570087e3cElliott Hughes#endif 7857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers InitEntryPoints(&entrypoints_); 79c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes} 80c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes 81c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughesvoid Thread::SetDebuggerUpdatesEnabled(bool enabled) { 82c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes LOG(INFO) << "Turning debugger updates " << (enabled ? "on" : "off") << " for " << *this; 83776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#if !defined(ART_USE_LLVM_COMPILER) 8457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers ChangeDebuggerEntryPoint(&entrypoints_, enabled); 85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#else 86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UNIMPLEMENTED(FATAL); 87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 883ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee} 893ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee 90caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Thread::InitTid() { 91caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom tid_ = ::art::GetTid(); 92caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 93caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 94caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Thread::InitAfterFork() { 958029cbe626a467b344ff84d86170d757aa12ecd4Elliott Hughes // One thread (us) survived the fork, but we have a new tid so we need to 968029cbe626a467b344ff84d86170d757aa12ecd4Elliott Hughes // update the value stashed in this Thread*. 97caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom InitTid(); 98caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 99caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 10078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromvoid* Thread::CreateCallback(void* arg) { 10193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes Thread* self = reinterpret_cast<Thread*>(arg); 102462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes self->Init(); 10393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 10493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // Wait until it's safe to start running code. (There may have been a suspend-all 10593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // in progress while we were starting up.) 106462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes Runtime* runtime = Runtime::Current(); 10793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes runtime->GetThreadList()->WaitForGo(); 10893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 10947179f76e3f03fe3eb21dfb081d50733ca316371Elliott Hughes { 110365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(self); 111365c10235438607541fa2259a5fec48061b90bd8Ian Rogers { 112365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SirtRef<String> thread_name(self->GetThreadName(ts)); 113365c10235438607541fa2259a5fec48061b90bd8Ian Rogers self->SetThreadName(thread_name->ToModifiedUtf8().c_str()); 114365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 11547179f76e3f03fe3eb21dfb081d50733ca316371Elliott Hughes 116365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Dbg::PostThreadStart(self); 11793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 118365c10235438607541fa2259a5fec48061b90bd8Ian Rogers // Invoke the 'run' method of our java.lang.Thread. 119365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(self->peer_ != NULL); 120365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* receiver = self->peer_; 121365c10235438607541fa2259a5fec48061b90bd8Ian Rogers jmethodID mid = WellKnownClasses::java_lang_Thread_run; 122365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Method* m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(ts.DecodeMethod(mid)); 123365c10235438607541fa2259a5fec48061b90bd8Ian Rogers m->Invoke(self, receiver, NULL, NULL); 124365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 12593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 12693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // Detach. 12793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes runtime->GetThreadList()->Unregister(); 12893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 129b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro return NULL; 130b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 131b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 132365c10235438607541fa2259a5fec48061b90bd8Ian Rogersstatic void SetVmData(const ScopedJniThreadState& ts, Object* managed_thread, 133365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Thread* native_thread) { 134365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Field* f = ts.DecodeField(WellKnownClasses::java_lang_Thread_vmData); 135af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes f->SetInt(managed_thread, reinterpret_cast<uintptr_t>(native_thread)); 13693e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes} 13793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 138365c10235438607541fa2259a5fec48061b90bd8Ian RogersThread* Thread::FromManagedThread(const ScopedJniThreadState& ts, Object* thread_peer) { 139365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Field* f = ts.DecodeField(WellKnownClasses::java_lang_Thread_vmData); 140af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes return reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetInt(thread_peer))); 141761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes} 142761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes 143365c10235438607541fa2259a5fec48061b90bd8Ian RogersThread* Thread::FromManagedThread(const ScopedJniThreadState& ts, jobject java_thread) { 144365c10235438607541fa2259a5fec48061b90bd8Ian Rogers return FromManagedThread(ts, ts.Decode<Object*>(java_thread)); 14501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes} 14601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 147ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughesstatic size_t FixStackSize(size_t stack_size) { 1487502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // A stack size of zero means "use the default". 149d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes if (stack_size == 0) { 150d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes stack_size = Runtime::Current()->GetDefaultStackSize(); 151d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 15261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 1536414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom // Dalvik used the bionic pthread default stack size for native threads, 1546414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom // so include that here to support apps that expect large native stacks. 1556414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom stack_size += 1 * MB; 1566414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom 1577502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // It's not possible to request a stack smaller than the system-defined PTHREAD_STACK_MIN. 1587502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes if (stack_size < PTHREAD_STACK_MIN) { 1597502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes stack_size = PTHREAD_STACK_MIN; 1607502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes } 1617502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 1627502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // It's likely that callers are trying to ensure they have at least a certain amount of 1637502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // stack space, so we should add our reserved space on top of what they requested, rather 1647502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // than implicitly take it away from them. 1657502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes stack_size += Thread::kStackOverflowReservedBytes; 1667502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 1677502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // Some systems require the stack size to be a multiple of the system page size, so round up. 1687502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes stack_size = RoundUp(stack_size, kPageSize); 1697502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 1707502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes return stack_size; 1717502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes} 1727502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 173d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughesstatic void SigAltStack(stack_t* new_stack, stack_t* old_stack) { 174d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes if (sigaltstack(new_stack, old_stack) == -1) { 175d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes PLOG(FATAL) << "sigaltstack failed"; 176d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes } 177d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes} 178d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 179d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughesstatic void SetUpAlternateSignalStack() { 180d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes // Create and set an alternate signal stack. 181d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes stack_t ss; 182d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_sp = new uint8_t[SIGSTKSZ]; 183d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_size = SIGSTKSZ; 184d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_flags = 0; 185d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes CHECK(ss.ss_sp != NULL); 186d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SigAltStack(&ss, NULL); 187d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 188d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes // Double-check that it worked. 189d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_sp = NULL; 190d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SigAltStack(NULL, &ss); 191d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes VLOG(threads) << "Alternate signal stack is " << PrettySize(ss.ss_size) << " at " << ss.ss_sp; 192d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes} 193d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 194d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughesstatic void TearDownAlternateSignalStack() { 195d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes // Get the pointer so we can free the memory. 196d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes stack_t ss; 197d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SigAltStack(NULL, &ss); 198d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes uint8_t* allocated_signal_stack = reinterpret_cast<uint8_t*>(ss.ss_sp); 199d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 200d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes // Tell the kernel to stop using it. 201d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_sp = NULL; 202d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes ss.ss_flags = SS_DISABLE; 2034c5231d2cd83536584f7f1063d0afffa124fcec4Elliott Hughes ss.ss_size = SIGSTKSZ; // Avoid ENOMEM failure with Mac OS' buggy libc. 204d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SigAltStack(&ss, NULL); 205d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 206d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes // Free it. 207d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes delete[] allocated_signal_stack; 208d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes} 209d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 210365c10235438607541fa2259a5fec48061b90bd8Ian Rogersvoid Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size) { 211365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Thread* native_thread = new Thread; 212365c10235438607541fa2259a5fec48061b90bd8Ian Rogers { 213365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(env); 214365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* peer = ts.Decode<Object*>(java_peer); 215365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(peer != NULL); 216365c10235438607541fa2259a5fec48061b90bd8Ian Rogers native_thread->peer_ = peer; 2177502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 218365c10235438607541fa2259a5fec48061b90bd8Ian Rogers stack_size = FixStackSize(stack_size); 2197502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 220365c10235438607541fa2259a5fec48061b90bd8Ian Rogers // Thread.start is synchronized, so we know that vmData is 0, 221365c10235438607541fa2259a5fec48061b90bd8Ian Rogers // and know that we're not racing to assign it. 222365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SetVmData(ts, peer, native_thread); 22393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 224365c10235438607541fa2259a5fec48061b90bd8Ian Rogers int pthread_create_result = 0; 225365c10235438607541fa2259a5fec48061b90bd8Ian Rogers { 226365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedThreadStateChange tsc(Thread::Current(), kVmWait); 227365c10235438607541fa2259a5fec48061b90bd8Ian Rogers pthread_t new_pthread; 228365c10235438607541fa2259a5fec48061b90bd8Ian Rogers pthread_attr_t attr; 229365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread"); 230365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED), "PTHREAD_CREATE_DETACHED"); 231365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size); 232365c10235438607541fa2259a5fec48061b90bd8Ian Rogers pthread_create_result = pthread_create(&new_pthread, &attr, Thread::CreateCallback, native_thread); 233365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread"); 234365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 23561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 236365c10235438607541fa2259a5fec48061b90bd8Ian Rogers if (pthread_create_result != 0) { 237365c10235438607541fa2259a5fec48061b90bd8Ian Rogers // pthread_create(3) failed, so clean up. 238365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SetVmData(ts, peer, 0); 239365c10235438607541fa2259a5fec48061b90bd8Ian Rogers delete native_thread; 24057aba86f29d7e795bf7e68c65cc464d2291b6af1Elliott Hughes 241365c10235438607541fa2259a5fec48061b90bd8Ian Rogers std::string msg(StringPrintf("pthread_create (%s stack) failed: %s", 242365c10235438607541fa2259a5fec48061b90bd8Ian Rogers PrettySize(stack_size).c_str(), strerror(pthread_create_result))); 243365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Thread::Current()->ThrowOutOfMemoryError(msg.c_str()); 244365c10235438607541fa2259a5fec48061b90bd8Ian Rogers return; 245365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 246365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 24793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // Let the child know when it's safe to start running. 24893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes Runtime::Current()->GetThreadList()->SignalGo(native_thread); 24993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes} 25061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 251462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughesvoid Thread::Init() { 252462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // This function does all the initialization that must be run by the native thread it applies to. 253462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // (When we create a new thread from managed code, we allocate the Thread* in Thread::Create so 254462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // we can handshake with the corresponding native thread when it's ready.) Check this native 255462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // thread hasn't been through here already... 256cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes CHECK(Thread::Current() == NULL); 257cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 258d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SetUpAlternateSignalStack(); 25993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes InitCpu(); 26093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes InitFunctionPointers(); 2615d76c435082332ef79a22962386fa92a0870e378Ian Rogers InitCardTable(); 26261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 263462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes Runtime* runtime = Runtime::Current(); 264462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes CHECK(runtime != NULL); 265462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes 266462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes thin_lock_id_ = runtime->GetThreadList()->AllocThreadId(); 2670d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes pthread_self_ = pthread_self(); 268be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 269caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom InitTid(); 27093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes InitStackHwm(); 271dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 2723147a2347d4fd775d51ec0a558955332beb9d1feElliott Hughes CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach"); 273a5780dad67556297c8ca5f2608c53b193e6c4514Elliott Hughes 27493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes jni_env_ = new JNIEnvExt(this, runtime->GetJavaVM()); 2755fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 2767a3aeb4d7580164c6a6905c63b96823b77ff5a64Elliott Hughes runtime->GetThreadList()->Register(); 27793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes} 27893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 279365c10235438607541fa2259a5fec48061b90bd8Ian RogersThread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_group) { 280cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes Thread* self = new Thread; 281462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes self->Init(); 2825fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 28334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes self->SetState(kNative); 284726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes 285cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // If we're the main thread, ClassLinker won't be created until after we're attached, 286cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // so that thread needs a two-stage attach. Regular threads don't need this hack. 287d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // In the compiler, all threads need this hack, because no-one's going to be getting 288d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // a native peer! 289d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes if (self->thin_lock_id_ != ThreadList::kMainId && !Runtime::Current()->IsCompiler()) { 290462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes self->CreatePeer(thread_name, as_daemon, thread_group); 29106e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes } else { 29206e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes // These aren't necessary, but they improve diagnostics for unit tests & command-line tools. 29322869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes if (thread_name != NULL) { 29422869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes self->name_->assign(thread_name); 29522869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes ::art::SetThreadName(thread_name); 29622869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes } 29736e0a955e48e9357bff1eab783e493107ebfff62Ian Rogers } 298cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 299cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes self->GetJniEnv()->locals.AssertEmpty(); 3005fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes return self; 3015fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes} 3025fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 303365c10235438607541fa2259a5fec48061b90bd8Ian Rogersvoid Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group) { 304365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Runtime* runtime = Runtime::Current(); 305365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(runtime->IsStarted()); 3065fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes JNIEnv* env = jni_env_; 3075fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 308462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes if (thread_group == NULL) { 309365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group = runtime->GetMainThreadGroup(); 310462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes } 311726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes ScopedLocalRef<jobject> thread_name(env, env->NewStringUTF(name)); 3128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes jint thread_priority = GetNativePriority(); 3135fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes jboolean thread_is_daemon = as_daemon; 3145fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 315eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes ScopedLocalRef<jobject> peer(env, env->AllocObject(WellKnownClasses::java_lang_Thread)); 316726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes peer_ = DecodeJObject(peer.get()); 3175d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers if (peer_ == NULL) { 3185d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers CHECK(IsExceptionPending()); 3195d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return; 3205d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 321eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes env->CallNonvirtualVoidMethod(peer.get(), 322eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes WellKnownClasses::java_lang_Thread, 323eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes WellKnownClasses::java_lang_Thread_init, 324365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group, thread_name.get(), thread_priority, thread_is_daemon); 3259a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson CHECK(!IsExceptionPending()) << " " << PrettyTypeOf(GetException()); 326d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 327365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(this); 328365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SetVmData(ts, peer_, Thread::Current()); 329365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SirtRef<String> peer_thread_name(GetThreadName(ts)); 33000fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom if (peer_thread_name.get() == NULL) { 33100fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // The Thread constructor should have set the Thread.name to a 33200fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // non-null value. However, because we can run without code 33300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // available (in the compiler, in tests), we manually assign the 33400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // fields the constructor should have set. 335365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ts.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->SetBoolean(peer_, thread_is_daemon); 336365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ts.DecodeField(WellKnownClasses::java_lang_Thread_group)->SetObject(peer_, ts.Decode<Object*>(thread_group)); 337365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ts.DecodeField(WellKnownClasses::java_lang_Thread_name)->SetObject(peer_, ts.Decode<Object*>(thread_name.get())); 338365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ts.DecodeField(WellKnownClasses::java_lang_Thread_priority)->SetInt(peer_, thread_priority); 339365c10235438607541fa2259a5fec48061b90bd8Ian Rogers peer_thread_name.reset(GetThreadName(ts)); 34000fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 341225f5a1df25241babd16cdba54056b9e2cd166a2Elliott Hughes // 'thread_name' may have been null, so don't trust 'peer_thread_name' to be non-null. 34200fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom if (peer_thread_name.get() != NULL) { 343899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes SetThreadName(peer_thread_name->ToModifiedUtf8().c_str()); 34400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 34561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 34661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 347899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughesvoid Thread::SetThreadName(const char* name) { 348899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes name_->assign(name); 349899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes ::art::SetThreadName(name); 350899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes Dbg::DdmSendThreadNotification(this, CHUNK_TYPE("THNM")); 351899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes} 352899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes 353be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughesvoid Thread::InitStackHwm() { 354e188419b971936086a188843378375f5ced13724Elliott Hughes void* stack_base; 355e188419b971936086a188843378375f5ced13724Elliott Hughes size_t stack_size; 356e188419b971936086a188843378375f5ced13724Elliott Hughes GetThreadStack(stack_base, stack_size); 35736ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 35836ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // TODO: include this in the thread dumps; potentially useful in SIGQUIT output? 359e188419b971936086a188843378375f5ced13724Elliott Hughes VLOG(threads) << StringPrintf("Native stack is at %p (%s)", stack_base, PrettySize(stack_size).c_str()); 360e188419b971936086a188843378375f5ced13724Elliott Hughes 361e188419b971936086a188843378375f5ced13724Elliott Hughes stack_begin_ = reinterpret_cast<byte*>(stack_base); 362e188419b971936086a188843378375f5ced13724Elliott Hughes stack_size_ = stack_size; 36336ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 364932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers if (stack_size_ <= kStackOverflowReservedBytes) { 3653d30d9b09c16542d41554aad9f46ec9109ba5cb5Elliott Hughes LOG(FATAL) << "Attempt to attach a thread with a too-small stack (" << stack_size_ << " bytes)"; 366be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 367449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes 368e188419b971936086a188843378375f5ced13724Elliott Hughes // TODO: move this into the Linux GetThreadStack implementation. 369e188419b971936086a188843378375f5ced13724Elliott Hughes#if !defined(__APPLE__) 37036ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // If we're the main thread, check whether we were run with an unlimited stack. In that case, 37136ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // glibc will have reported a 2GB stack for our 32-bit process, and our stack overflow detection 37236ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // will be broken because we'll die long before we get close to 2GB. 37336ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes if (thin_lock_id_ == 1) { 37436ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes rlimit stack_limit; 37536ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes if (getrlimit(RLIMIT_STACK, &stack_limit) == -1) { 37636ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes PLOG(FATAL) << "getrlimit(RLIMIT_STACK) failed"; 37736ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes } 37836ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes if (stack_limit.rlim_cur == RLIM_INFINITY) { 37936ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // Find the default stack size for new threads... 38036ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes pthread_attr_t default_attributes; 38136ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes size_t default_stack_size; 38236ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes CHECK_PTHREAD_CALL(pthread_attr_init, (&default_attributes), "default stack size query"); 38336ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes CHECK_PTHREAD_CALL(pthread_attr_getstacksize, (&default_attributes, &default_stack_size), 38436ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes "default stack size query"); 38536ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes CHECK_PTHREAD_CALL(pthread_attr_destroy, (&default_attributes), "default stack size query"); 38636ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 38736ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes // ...and use that as our limit. 38836ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes size_t old_stack_size = stack_size_; 38936ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes stack_size_ = default_stack_size; 39036ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes stack_begin_ += (old_stack_size - stack_size_); 391faf4ba01738400f418b45c4323aa9e8e6b6ba2a0Elliott Hughes VLOG(threads) << "Limiting unlimited stack (reported as " << PrettySize(old_stack_size) << ")" 392faf4ba01738400f418b45c4323aa9e8e6b6ba2a0Elliott Hughes << " to " << PrettySize(stack_size_) 393faf4ba01738400f418b45c4323aa9e8e6b6ba2a0Elliott Hughes << " with base " << reinterpret_cast<void*>(stack_begin_); 39436ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes } 39536ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes } 396e188419b971936086a188843378375f5ced13724Elliott Hughes#endif 39736ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 398932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set stack_end_ to the bottom of the stack saving space of stack overflows 399932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers ResetDefaultStackEnd(); 400449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes 401449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes // Sanity check. 402449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes int stack_variable; 403398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes CHECK_GT(&stack_variable, reinterpret_cast<void*>(stack_end_)); 404be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes} 405be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 406899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughesvoid Thread::Dump(std::ostream& os, bool full) const { 407899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes if (full) { 408899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes DumpState(os); 409899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes DumpStack(os); 410899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes } else { 411899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes os << "Thread["; 412899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes if (GetThinLockId() != 0) { 413899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes // If we're in kStarting, we won't have a thin lock id or tid yet. 414899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes os << GetThinLockId() 415899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes << ",tid=" << GetTid() << ','; 416899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes } 417899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes os << GetState() 418899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes << ",Thread*=" << this 419ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes << ",peer=" << peer_ 420899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes << ",\"" << *name_ << "\"" 421899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes << "]"; 422e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes } 423d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes} 424d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 425365c10235438607541fa2259a5fec48061b90bd8Ian RogersString* Thread::GetThreadName(const ScopedJniThreadState& ts) const { 426365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Field* f = ts.DecodeField(WellKnownClasses::java_lang_Thread_name); 427af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes return (peer_ != NULL) ? reinterpret_cast<String*>(f->GetObject(peer_)) : NULL; 428fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes} 429fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 430ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughesvoid Thread::GetThreadName(std::string& name) const { 431ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes name.assign(*name_); 432ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes} 433ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 434abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughesvoid Thread::DumpState(std::ostream& os, const Thread* thread, pid_t tid) { 435d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes std::string group_name; 436d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes int priority; 437d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes bool is_daemon = false; 438d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 439abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (thread != NULL && thread->peer_ != NULL) { 440365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(Thread::Current()); 441365c10235438607541fa2259a5fec48061b90bd8Ian Rogers priority = ts.DecodeField(WellKnownClasses::java_lang_Thread_priority)->GetInt(thread->peer_); 442365c10235438607541fa2259a5fec48061b90bd8Ian Rogers is_daemon = ts.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->GetBoolean(thread->peer_); 443d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 444365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* thread_group = thread->GetThreadGroup(ts); 445d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes if (thread_group != NULL) { 446365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Field* group_name_field = ts.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name); 447af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes String* group_name_string = reinterpret_cast<String*>(group_name_field->GetObject(thread_group)); 448d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes group_name = (group_name_string != NULL) ? group_name_string->ToModifiedUtf8() : "<null>"; 449d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 450d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } else { 451d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes priority = GetNativePriority(); 452dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes } 453d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 454abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes std::string scheduler_group_name(GetSchedulerGroupName(tid)); 4551bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes if (scheduler_group_name.empty()) { 4561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes scheduler_group_name = "default"; 457d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 458d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 459abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (thread != NULL) { 460abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << '"' << *thread->name_ << '"'; 461abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (is_daemon) { 462abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " daemon"; 463abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 464abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " prio=" << priority 465abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " tid=" << thread->GetThinLockId() 466abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " " << thread->GetState() << "\n"; 467abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } else { 468289be85116aaf7c48413858b5d0448868b4e61f3Elliott Hughes os << '"' << ::art::GetThreadName(tid) << '"' 469abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " prio=" << priority 470abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " (not attached)\n"; 471abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 472abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 473abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (thread != NULL) { 474abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " | group=\"" << group_name << "\"" 475abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " sCount=" << thread->suspend_count_ 476abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " dsCount=" << thread->debug_suspend_count_ 477abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " obj=" << reinterpret_cast<void*>(thread->peer_) 478abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " self=" << reinterpret_cast<const void*>(thread) << "\n"; 479d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 4800d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes 481abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " | sysTid=" << tid 482abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " nice=" << getpriority(PRIO_PROCESS, tid) 4830d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes << " cgrp=" << scheduler_group_name; 4840d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes if (thread != NULL) { 4850d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes int policy; 4860d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes sched_param sp; 4870d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes CHECK_PTHREAD_CALL(pthread_getschedparam, (thread->pthread_self_, &policy, &sp), __FUNCTION__); 4880d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes os << " sched=" << policy << "/" << sp.sched_priority 4890d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes << " handle=" << reinterpret_cast<void*>(thread->pthread_self_); 4900d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes } 4910d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes os << "\n"; 492d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 493d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // Grab the scheduler stats for this thread. 494d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes std::string scheduler_stats; 495abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (ReadFileToString(StringPrintf("/proc/self/task/%d/schedstat", tid), &scheduler_stats)) { 496d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes scheduler_stats.resize(scheduler_stats.size() - 1); // Lose the trailing '\n'. 497d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } else { 498d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes scheduler_stats = "0 0 0"; 499d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 500d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 501d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int utime = 0; 502d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int stime = 0; 503d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int task_cpu = 0; 504abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes GetTaskStats(tid, utime, stime, task_cpu); 505d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 506d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes os << " | schedstat=( " << scheduler_stats << " )" 507d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes << " utm=" << utime 508d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes << " stm=" << stime 509abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " core=" << task_cpu 510abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " HZ=" << sysconf(_SC_CLK_TCK) << "\n"; 511abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (thread != NULL) { 512abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " | stack=" << reinterpret_cast<void*>(thread->stack_begin_) << "-" << reinterpret_cast<void*>(thread->stack_end_) 513abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " stackSize=" << PrettySize(thread->stack_size_) << "\n"; 514abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 515abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes} 516abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 517abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughesvoid Thread::DumpState(std::ostream& os) const { 518abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes Thread::DumpState(os, this, GetTid()); 519a09576416788b916095739e43a16917e7948f3a4Elliott Hughes} 520a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 5210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersstruct StackDumpVisitor : public StackVisitor { 5220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers StackDumpVisitor(std::ostream& os, const Thread* thread) : 5230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers StackVisitor(thread->GetManagedStack(), thread->GetTraceStack()), last_method(NULL), 5240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers last_line_number(0), repetition_count(0), os(os), thread(thread), frame_count(0) { 525d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 526d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 527bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers virtual ~StackDumpVisitor() { 528e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes if (frame_count == 0) { 529e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes os << " (no managed stack frames)\n"; 530e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes } 531d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 532d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 5330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool VisitFrame() { 5340399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* m = GetMethod(); 5350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (m->IsRuntimeMethod()) { 536530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 5379086572fa809d1a19d886b467e4da3ce42016982Ian Rogers } 53828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers const int kMaxRepetition = 3; 539d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes Class* c = m->GetDeclaringClass(); 5408e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 541b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers const DexCache* dex_cache = c->GetDexCache(); 542b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers int line_number = -1; 543b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers if (dex_cache != NULL) { // be tolerant of bad input 544b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers const DexFile& dex_file = class_linker->FindDexFile(dex_cache); 5450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers line_number = dex_file.GetLineNumFromPC(m, GetDexPc()); 546b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers } 54728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (line_number == last_line_number && last_method == m) { 54828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers repetition_count++; 549d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } else { 55028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (repetition_count >= kMaxRepetition) { 55128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << " ... repeated " << (repetition_count - kMaxRepetition) << " times\n"; 55228ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 55328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers repetition_count = 0; 55428ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers last_line_number = line_number; 55528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers last_method = m; 55628ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 55728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (repetition_count < kMaxRepetition) { 55828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << " at " << PrettyMethod(m, false); 55928ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (m->IsNative()) { 56028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << "(Native method)"; 56128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } else { 5626d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers mh.ChangeMethod(m); 5636d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers const char* source_file(mh.GetDeclaringClassSourceFile()); 5646d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers os << "(" << (source_file != NULL ? source_file : "unavailable") 56528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers << ":" << line_number << ")"; 56628ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 56728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << "\n"; 568d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 5698e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 5708e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes if (frame_count++ == 0) { 5718e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Monitor::DescribeWait(os, thread); 5728e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } 573530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 574d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 5756d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers MethodHelper mh; 57628ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers Method* last_method; 57728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers int last_line_number; 57828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers int repetition_count; 579d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes std::ostream& os; 5808e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes const Thread* thread; 5818e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes int frame_count; 582d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes}; 583d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 584d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughesvoid Thread::DumpStack(std::ostream& os) const { 585ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes // If we're currently in native code, dump that stack before dumping the managed stack. 58634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes if (GetState() == kNative || GetState() == kVmWait) { 58746e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes DumpKernelStack(os, GetTid(), " kernel: ", false); 58846e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes DumpNativeStack(os, GetTid(), " native: ", false); 589ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } 5908e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes StackDumpVisitor dumper(os, this); 5910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dumper.WalkStack(); 592e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes} 593e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 59434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughesvoid Thread::SetStateWithoutSuspendCheck(ThreadState new_state) { 595a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes volatile void* raw = reinterpret_cast<volatile void*>(&state_); 596a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw); 597a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes android_atomic_release_store(new_state, addr); 598a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes} 599a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes 60034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott HughesThreadState Thread::SetState(ThreadState new_state) { 60134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes ThreadState old_state = state_; 6020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (old_state == kRunnable) { 6030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Non-runnable states are points where we expect thread suspension can occur. 6040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers AssertThreadSuspensionIsAllowable(); 6050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 6060399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 6078d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes if (old_state == new_state) { 6088d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes return old_state; 6098d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } 6108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 6118d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes volatile void* raw = reinterpret_cast<volatile void*>(&state_); 6128d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw); 6138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 61434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes if (new_state == kRunnable) { 6158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes /* 61634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes * Change our status to kRunnable. The transition requires 61781ff3184e7eb8de4605c7646674ea4f9fa29b5f3Elliott Hughes * that we check for pending suspension, because the runtime considers 6188d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * us to be "asleep" in all other states, and another thread could 6198d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * be performing a GC now. 6208d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6218d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * The order of operations is very significant here. One way to 6228d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * do this wrong is: 6238d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6248d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * GCing thread Our thread (in kNative) 6258d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * ------------ ---------------------- 6268d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * check suspend count (== 0) 6278d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * SuspendAllThreads() 6288d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * grab suspend-count lock 6298d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * increment all suspend counts 6308d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * release suspend-count lock 6318d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * check thread state (== kNative) 6328d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * all are suspended, begin GC 6338d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * set state to kRunnable 6348d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * (continue executing) 6358d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6368d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * We can correct this by grabbing the suspend-count lock and 6378d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * performing both of our operations (check suspend count, set 6388d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * state) while holding it, now we need to grab a mutex on every 6398d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * transition to kRunnable. 6408d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6418d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * What we do instead is change the order of operations so that 6428d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * the transition to kRunnable happens first. If we then detect 6438d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * that the suspend count is nonzero, we switch to kSuspended. 6448d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6458d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Appropriate compiler and memory barriers are required to ensure 6468d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * that the operations are observed in the expected order. 6478d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6488d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * This does create a small window of opportunity where a GC in 6498d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * progress could observe what appears to be a running thread (if 6508d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * it happens to look between when we set to kRunnable and when we 6518d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * switch to kSuspended). At worst this only affects assertions 6528d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * and thread logging. (We could work around it with some sort 6538d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * of intermediate "pre-running" state that is generally treated 6548d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * as equivalent to running, but that doesn't seem worthwhile.) 6558d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6568d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * We can also solve this by combining the "status" and "suspend 6578d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * count" fields into a single 32-bit value. This trades the 6588d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * store/load barrier on transition to kRunnable for an atomic RMW 6598d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * op on all transitions and all suspend count updates (also, all 6608d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * accesses to status or the thread count require bit-fiddling). 6618d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * It also eliminates the brief transition through kRunnable when 6628d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * the thread is supposed to be suspended. This is possibly faster 6638d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * on SMP and slightly more correct, but less convenient. 6648d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */ 6650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers AssertThreadSuspensionIsAllowable(); 6668d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes android_atomic_acquire_store(new_state, addr); 66706e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes ANNOTATE_IGNORE_READS_BEGIN(); 66806e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes int suspend_count = suspend_count_; 66906e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes ANNOTATE_IGNORE_READS_END(); 67006e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes if (suspend_count != 0) { 6718d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes Runtime::Current()->GetThreadList()->FullSuspendCheck(this); 6728d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } 6738d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } else { 6748d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes /* 67534e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes * Not changing to kRunnable. No additional work required. 6768d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 6778d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * We use a releasing store to ensure that, if we were runnable, 6788d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * any updates we previously made to objects on the managed heap 6798d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * will be observed before the state change. 6808d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */ 6818d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes android_atomic_release_store(new_state, addr); 6828d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } 6838d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 6848d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes return old_state; 6858d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes} 6868d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 687761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool Thread::IsSuspended() { 68806e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes ANNOTATE_IGNORE_READS_BEGIN(); 68906e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes int suspend_count = suspend_count_; 69006e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes ANNOTATE_IGNORE_READS_END(); 69134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes return suspend_count != 0 && GetState() != kRunnable; 692761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes} 693761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes 694ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughesstatic void ReportThreadSuspendTimeout(Thread* waiting_thread) { 695ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes Runtime* runtime = Runtime::Current(); 696ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes std::ostringstream ss; 697ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes ss << "Thread suspend timeout waiting for thread " << *waiting_thread << "\n"; 698ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes runtime->DumpLockHolders(ss); 699ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes ss << "\n"; 700ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes runtime->GetThreadList()->DumpLocked(ss); 701ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes LOG(FATAL) << ss.str(); 702ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes} 703ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes 7048d768a954b101a9532f980253ac46be2c53aba11Elliott Hughesvoid Thread::WaitUntilSuspended() { 70521a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes static const useconds_t kTimeoutUs = 30 * 1000000; // 30s. 70621a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes 70721a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes useconds_t total_delay = 0; 7088d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes useconds_t delay = 0; 70934e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes while (GetState() == kRunnable) { 71021a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes if (total_delay >= kTimeoutUs) { 711ff7380681c50129ff689a11ac0f49512b4be7295Elliott Hughes ReportThreadSuspendTimeout(this); 71221a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes } 7138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes useconds_t new_delay = delay * 2; 7148d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes CHECK_GE(new_delay, delay); 7158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes delay = new_delay; 7168d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes if (delay == 0) { 7178d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes sched_yield(); 7187664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier // Default to 1 milliseconds (note that this gets multiplied by 2 before 7197664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier // the first sleep) 7207664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier delay = 500; 7218d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } else { 7228d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes usleep(delay); 72321a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes total_delay += delay; 7248d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } 7258d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes } 7268d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes} 7278d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 728be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughesvoid Thread::ThreadExitCallback(void* arg) { 729be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Thread* self = reinterpret_cast<Thread*>(arg); 730be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes LOG(FATAL) << "Native thread exited without calling DetachCurrentThread: " << *self; 731b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 732b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 733be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughesvoid Thread::Startup() { 734b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Allocate a TLS slot. 7358d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes CHECK_PTHREAD_CALL(pthread_key_create, (&Thread::pthread_key_self_, Thread::ThreadExitCallback), "self key"); 736b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 737b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Double-check the TLS slot allocation. 738b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (pthread_getspecific(pthread_key_self_) != NULL) { 7393d30d9b09c16542d41554aad9f46ec9109ba5cb5Elliott Hughes LOG(FATAL) << "Newly-created pthread TLS slot is not NULL"; 740b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 741038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes} 742038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes 743038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughesvoid Thread::FinishStartup() { 744365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Runtime* runtime = Runtime::Current(); 745365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(runtime->IsStarted()); 746b82b6878fb000d4731063b1bf15c39ff7c50b61fBrian Carlstrom Thread* self = Thread::Current(); 747b82b6878fb000d4731063b1bf15c39ff7c50b61fBrian Carlstrom 74801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Finish attaching the main thread. 749af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes ScopedThreadStateChange tsc(self, kRunnable); 750365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup()); 7519a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson 7529a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson InitBoxingMethods(); 753af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes Runtime::Current()->GetClassLinker()->RunRootClinits(); 754b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 755b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 756c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughesvoid Thread::Shutdown() { 7578d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes CHECK_PTHREAD_CALL(pthread_key_delete, (Thread::pthread_key_self_), "self key"); 758c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 759c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 760dcc247493fd8fb243e335c3ec08e5e625896a47cElliott HughesThread::Thread() 7610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers : suspend_count_(0), 7620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers card_table_(NULL), 7630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers exception_(NULL), 7640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers stack_end_(NULL), 7650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers managed_stack_(), 7660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers jni_env_(NULL), 7670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self_(NULL), 7680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers state_(kNative), 76947179f76e3f03fe3eb21dfb081d50733ca316371Elliott Hughes peer_(NULL), 7700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers stack_begin_(NULL), 7710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers stack_size_(0), 7720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers thin_lock_id_(0), 7730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers tid_(0), 774e62934d85fbc2d935afdad57eeade39ecbd7440aElliott Hughes wait_mutex_(new Mutex("a thread wait mutex")), 775e62934d85fbc2d935afdad57eeade39ecbd7440aElliott Hughes wait_cond_(new ConditionVariable("a thread wait condition variable")), 7768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes wait_monitor_(NULL), 7778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes interrupted_(false), 778dc33ad5db2dc6ed9b76d5219888626a604debbe1Elliott Hughes wait_next_(NULL), 7798e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes monitor_enter_object_(NULL), 780dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes top_sirt_(NULL), 781dc33ad5db2dc6ed9b76d5219888626a604debbe1Elliott Hughes runtime_(NULL), 78285d1545e985ac689db4bad7849880e843707c862Elliott Hughes class_loader_override_(NULL), 783418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes long_jump_context_(NULL), 784726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes throwing_OutOfMemoryError_(false), 7850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers debug_suspend_count_(0), 786e343b76af81a005ef64f5e75a555389fd9147dabjeffhao debug_invoke_req_(new DebugInvokeReq), 787899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes trace_stack_(new std::vector<TraceStackFrame>), 7880399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers name_(new std::string(kThreadNameDuringStartup)), 7890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers no_thread_suspension_(0) { 790f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes CHECK_EQ((sizeof(Thread) % 4), 0U) << sizeof(Thread); 791ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes memset(&held_mutexes_[0], 0, sizeof(held_mutexes_)); 792dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 793dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 7947dc5166ea740359d381097a7ab382c1dd404055fElliott Hughesbool Thread::IsStillStarting() const { 7957dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // You might think you can check whether the state is kStarting, but for much of thread startup, 7967dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // the thread might also be in kVmWait. 7977dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // You might think you can check whether the peer is NULL, but the peer is actually created and 7987dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // assigned fairly early on, and needs to be. 7997dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // It turns out that the last thing to change is the thread name; that's a good proxy for "has 8007dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // this thread _ever_ entered kRunnable". 8017dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes return (*name_ == kThreadNameDuringStartup); 8027dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes} 8037dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes 804ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughesstatic void MonitorExitVisitor(const Object* object, void*) { 80502b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes Object* entered_monitor = const_cast<Object*>(object); 806ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes LOG(WARNING) << "Calling MonitorExit on object " << object << " (" << PrettyTypeOf(object) << ")" 807ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes << " left locked by native thread " << *Thread::Current() << " which is detaching"; 8085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes entered_monitor->MonitorExit(Thread::Current()); 80902b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes} 81002b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 811c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughesvoid Thread::Destroy() { 81202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes // On thread detach, all monitors entered with JNI MonitorEnter are automatically exited. 81393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes if (jni_env_ != NULL) { 81493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes jni_env_->monitors.VisitRoots(MonitorExitVisitor, NULL); 81593e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes } 81602b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 81729f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes if (peer_ != NULL) { 818c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes Thread* self = this; 81929f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes 820534da072d3db3beecbd74e5aa23d630d73695f2cElliott Hughes // We may need to call user-supplied managed code. 821365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(this); 822534da072d3db3beecbd74e5aa23d630d73695f2cElliott Hughes 823365c10235438607541fa2259a5fec48061b90bd8Ian Rogers HandleUncaughtExceptions(ts); 824365c10235438607541fa2259a5fec48061b90bd8Ian Rogers RemoveFromThreadGroup(ts); 825534da072d3db3beecbd74e5aa23d630d73695f2cElliott Hughes 82629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // this.vmData = 0; 827365c10235438607541fa2259a5fec48061b90bd8Ian Rogers SetVmData(ts, peer_, NULL); 82802b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 829c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes Dbg::PostThreadDeath(self); 83002b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 83129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // Thread.join() is implemented as an Object.wait() on the Thread.lock 83229f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // object. Signal anyone who is waiting. 833365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* lock = ts.DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(peer_); 834038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // (This conditional is only needed for tests, where Thread.lock won't have been set.) 8355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (lock != NULL) { 8365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock->MonitorEnter(self); 8375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock->NotifyAll(); 8385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock->MonitorExit(self); 8395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 8405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 841c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes} 84202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 843c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott HughesThread::~Thread() { 844c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes delete jni_env_; 84502b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes jni_env_ = NULL; 84602b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 84734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes SetState(kTerminated); 84885d1545e985ac689db4bad7849880e843707c862Elliott Hughes 84985d1545e985ac689db4bad7849880e843707c862Elliott Hughes delete wait_cond_; 85085d1545e985ac689db4bad7849880e843707c862Elliott Hughes delete wait_mutex_; 85185d1545e985ac689db4bad7849880e843707c862Elliott Hughes 852776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#if !defined(ART_USE_LLVM_COMPILER) 85385d1545e985ac689db4bad7849880e843707c862Elliott Hughes delete long_jump_context_; 854776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 855475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes 856475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes delete debug_invoke_req_; 857e343b76af81a005ef64f5e75a555389fd9147dabjeffhao delete trace_stack_; 858899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes delete name_; 859d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 860d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes TearDownAlternateSignalStack(); 861c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 862c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 863365c10235438607541fa2259a5fec48061b90bd8Ian Rogersvoid Thread::HandleUncaughtExceptions(const ScopedJniThreadState& ts) { 864accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes if (!IsExceptionPending()) { 865accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes return; 866accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes } 867accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Get and clear the exception. 868accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes Object* exception = GetException(); 869accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes ClearException(); 870accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 871accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // If the thread has its own handler, use that. 872365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* handler = 873365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ts.DecodeField(WellKnownClasses::java_lang_Thread_uncaughtHandler)->GetObject(peer_); 874accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes if (handler == NULL) { 875accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Otherwise use the thread group's default handler. 876365c10235438607541fa2259a5fec48061b90bd8Ian Rogers handler = GetThreadGroup(ts); 877accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes } 878accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 879accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Call the handler. 880af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes jmethodID mid = WellKnownClasses::java_lang_Thread$UncaughtExceptionHandler_uncaughtException; 881365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Method* m = handler->GetClass()->FindVirtualMethodForVirtualOrInterface(ts.DecodeMethod(mid)); 88277405796564c6c1353807cda18b28678a719bd68Elliott Hughes JValue args[2]; 883f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes args[0].SetL(peer_); 884f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes args[1].SetL(exception); 88577405796564c6c1353807cda18b28678a719bd68Elliott Hughes m->Invoke(this, handler, args, NULL); 886accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 887accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // If the handler threw, clear that exception too. 888accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes ClearException(); 889accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes} 8904514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom 891365c10235438607541fa2259a5fec48061b90bd8Ian RogersObject* Thread::GetThreadGroup(const ScopedJniThreadState& ts) const { 892365c10235438607541fa2259a5fec48061b90bd8Ian Rogers return ts.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(peer_); 893a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes} 894a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes 895365c10235438607541fa2259a5fec48061b90bd8Ian Rogersvoid Thread::RemoveFromThreadGroup(const ScopedJniThreadState& ts) { 8964514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom // this.group.removeThread(this); 8974514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom // group can be null if we're in the compiler or a test. 898365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Object* group = GetThreadGroup(ts); 8994514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom if (group != NULL) { 900af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes jmethodID mid = WellKnownClasses::java_lang_ThreadGroup_removeThread; 901365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Method* m = group->GetClass()->FindVirtualMethodForVirtualOrInterface(ts.DecodeMethod(mid)); 90277405796564c6c1353807cda18b28678a719bd68Elliott Hughes JValue args[1]; 903f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes args[0].SetL(peer_); 90477405796564c6c1353807cda18b28678a719bd68Elliott Hughes m->Invoke(this, group, args, NULL); 9054514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom } 9064514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom} 907accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 908408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogerssize_t Thread::NumSirtReferences() { 909a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers size_t count = 0; 91040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) { 911a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers count += cur->NumberOfReferences(); 912a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 913a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers return count; 914a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers} 915a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 916408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogersbool Thread::SirtContains(jobject obj) { 917408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object** sirt_entry = reinterpret_cast<Object**>(obj); 91840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) { 91940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom if (cur->Contains(sirt_entry)) { 920a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers return true; 921a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 922a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 9230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // JNI code invoked from portable code uses shadow frames rather than the SIRT. 9240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return managed_stack_.ShadowFramesContain(sirt_entry); 92528f1a147d77ec772db98bed890b50a9ddcff2365TDYa} 92628f1a147d77ec772db98bed890b50a9ddcff2365TDYa 9278dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liaovoid Thread::SirtVisitRoots(Heap::RootVisitor* visitor, void* arg) { 92840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) { 9298dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao size_t num_refs = cur->NumberOfReferences(); 9308dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao for (size_t j = 0; j < num_refs; j++) { 93140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom Object* object = cur->GetReference(j); 9325e73f9c8990819054f8e0a60061ee8beff1e024aBrian Carlstrom if (object != NULL) { 9335e73f9c8990819054f8e0a60061ee8beff1e024aBrian Carlstrom visitor(object, arg); 9345e73f9c8990819054f8e0a60061ee8beff1e024aBrian Carlstrom } 9358dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao } 9368dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao } 9378dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao} 9388dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao 939408f79aeb676251ba35667a64e86c20638d7cb0bIan RogersObject* Thread::DecodeJObject(jobject obj) { 9400cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers DCHECK(CanAccessDirectReferences()); 941408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers if (obj == NULL) { 942408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return NULL; 943408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 944408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectRef ref = reinterpret_cast<IndirectRef>(obj); 945408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectRefKind kind = GetIndirectRefKind(ref); 946408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers Object* result; 947408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers switch (kind) { 948408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers case kLocal: 949408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers { 95069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes IndirectReferenceTable& locals = jni_env_->locals; 951cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes result = const_cast<Object*>(locals.Get(ref)); 952408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers break; 953408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 954408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers case kGlobal: 955408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers { 956408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers JavaVMExt* vm = Runtime::Current()->GetJavaVM(); 957408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectReferenceTable& globals = vm->globals; 958408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers MutexLock mu(vm->globals_lock); 959cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes result = const_cast<Object*>(globals.Get(ref)); 960408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers break; 961408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 962408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers case kWeakGlobal: 963408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers { 964408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers JavaVMExt* vm = Runtime::Current()->GetJavaVM(); 965408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectReferenceTable& weak_globals = vm->weak_globals; 966408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers MutexLock mu(vm->weak_globals_lock); 967cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes result = const_cast<Object*>(weak_globals.Get(ref)); 968408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers if (result == kClearedJniWeakGlobal) { 969408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // This is a special case where it's okay to return NULL. 970408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return NULL; 971408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 972408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers break; 973408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 974408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers case kSirtOrInvalid: 975408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers default: 976408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // TODO: make stack indirect reference table lookup more efficient 977408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Check if this is a local reference in the SIRT 9780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (SirtContains(obj)) { 9790cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers result = *reinterpret_cast<Object**>(obj); // Read from SIRT 980c2dc62d1c9241dfe880a81698713c314b13aa63fElliott Hughes } else if (Runtime::Current()->GetJavaVM()->work_around_app_jni_bugs) { 981408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Assume an invalid local reference is actually a direct pointer. 982408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers result = reinterpret_cast<Object*>(obj); 983408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } else { 984a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes result = kInvalidIndirectRefObject; 985408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 986408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 987408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 988408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers if (result == NULL) { 9893f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes JniAbortF(NULL, "use of deleted %s %p", ToStr<IndirectRefKind>(kind).c_str(), obj); 990a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } else { 991a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes if (result != kInvalidIndirectRefObject) { 992b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->VerifyObject(result); 993a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } 994408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 995408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return result; 996408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers} 997408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 9980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass CountStackDepthVisitor : public StackVisitor { 9999b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 10000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CountStackDepthVisitor(const ManagedStack* stack, 10010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const std::vector<TraceStackFrame>* trace_stack) : 10020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers StackVisitor(stack, trace_stack), depth_(0), skip_depth_(0), 10030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers skipping_(true) {} 1004d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 10050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool VisitFrame() { 100629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // We want to skip frames up to and including the exception's constructor. 10079086572fa809d1a19d886b467e4da3ce42016982Ian Rogers // Note we also skip the frame if it doesn't have a method (namely the callee 10089086572fa809d1a19d886b467e4da3ce42016982Ian Rogers // save frame) 10090399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* m = GetMethod(); 10100399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (skipping_ && !m->IsRuntimeMethod() && 10110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers !Throwable::GetJavaLangThrowable()->IsAssignableFrom(m->GetDeclaringClass())) { 101229f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes skipping_ = false; 101329f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 101429f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes if (!skipping_) { 10150399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (!m->IsRuntimeMethod()) { // Ignore runtime frames (in particular callee save). 10166b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers ++depth_; 10176b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers } 101829f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } else { 101929f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes ++skip_depth_; 102029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 1021530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 10229b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 10239b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10249b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao int GetDepth() const { 1025aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers return depth_; 10269b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 10279b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 102829f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int GetSkipDepth() const { 102929f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes return skip_depth_; 103029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 103129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes 10329b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao private: 1033aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers uint32_t depth_; 103429f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes uint32_t skip_depth_; 103529f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes bool skipping_; 10369b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao}; 10379b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass BuildInternalStackTraceVisitor : public StackVisitor { 10399b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 10400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers explicit BuildInternalStackTraceVisitor(const ManagedStack* stack, 10410399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const std::vector<TraceStackFrame>* trace_stack, 10420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers int skip_depth) : 10430399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers StackVisitor(stack, trace_stack), skip_depth_(skip_depth), count_(0), dex_pc_trace_(NULL), 10440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_trace_(NULL) {} 1045283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers 1046365c10235438607541fa2259a5fec48061b90bd8Ian Rogers bool Init(int depth, const ScopedJniThreadState& ts) { 1047aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Allocate method trace with an extra slot that will hold the PC trace 10480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers SirtRef<ObjectArray<Object> > 10490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_trace(Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(depth + 1)); 10500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (method_trace.get() == NULL) { 1051283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return false; 1052726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes } 10530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers IntArray* dex_pc_trace = IntArray::Alloc(depth); 10540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (dex_pc_trace == NULL) { 1055283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return false; 1056726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes } 1057aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Save PC trace in last element of method trace, also places it into the 1058aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // object graph. 10590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_trace->Set(depth, dex_pc_trace); 10600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Set the Object*s and assert that no thread suspension is now possible. 10610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ts.Self()->StartAssertNoThreadSuspension(); 10620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_trace_ = method_trace.get(); 10630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dex_pc_trace_ = dex_pc_trace; 1064283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return true; 10659b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 10669b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers virtual ~BuildInternalStackTraceVisitor() { 10680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Thread::Current()->EndAssertNoThreadSuspension(); 10690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 10709b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool VisitFrame() { 10720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (method_trace_ == NULL || dex_pc_trace_ == NULL) { 1073530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; // We're probably trying to fillInStackTrace for an OutOfMemoryError. 1074726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes } 107529f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes if (skip_depth_ > 0) { 107629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes skip_depth_--; 1077530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 107829f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 10790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* m = GetMethod(); 10800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (m->IsRuntimeMethod()) { 10810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return true; // Ignore runtime frames (in particular callee save). 10826b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers } 10830399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_trace_->Set(count_, m); 10840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dex_pc_trace_->Set(count_, GetDexPc()); 1085aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers ++count_; 1086530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 10879b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 10889b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ObjectArray<Object>* GetInternalStackTrace() const { 10900399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return method_trace_; 10919b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 10929b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 10939b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao private: 109429f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // How many more frames to skip. 109529f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int32_t skip_depth_; 10960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Current position down stack trace. 1097aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers uint32_t count_; 10980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Array of dex PC values. 10990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers IntArray* dex_pc_trace_; 11000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // An array of the methods on the stack, the last entry is a reference to the PC trace. 1101aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers ObjectArray<Object>* method_trace_; 11029b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao}; 11039b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 110440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstromvoid Thread::PushSirt(StackIndirectReferenceTable* sirt) { 110540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom sirt->SetLink(top_sirt_); 110640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom top_sirt_ = sirt; 110740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom} 110840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom 110940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian CarlstromStackIndirectReferenceTable* Thread::PopSirt() { 111040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom CHECK(top_sirt_ != NULL); 111140381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom StackIndirectReferenceTable* sirt = top_sirt_; 111240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom top_sirt_ = top_sirt_->GetLink(); 111340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom return sirt; 111440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom} 111540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom 1116365c10235438607541fa2259a5fec48061b90bd8Ian Rogersjobject Thread::CreateInternalStackTrace(const ScopedJniThreadState& ts) const { 1117aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Compute depth of stack 11180399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CountStackDepthVisitor count_visitor(GetManagedStack(), GetTraceStack()); 11190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers count_visitor.WalkStack(); 11209b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao int32_t depth = count_visitor.GetDepth(); 112129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int32_t skip_depth = count_visitor.GetSkipDepth(); 11224417536522fd2a9d8215d8672331984769c9520bShih-wei Liao 1123aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Build internal stack trace 11240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers BuildInternalStackTraceVisitor build_trace_visitor(GetManagedStack(), GetTraceStack(), 11250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers skip_depth); 112677f74c1455bd8d29deb8a9367cea35deb930ed10Ian Rogers if (!build_trace_visitor.Init(depth, ts)) { 1127283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return NULL; // Allocation failed 1128283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers } 11290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers build_trace_visitor.WalkStack(); 1130365c10235438607541fa2259a5fec48061b90bd8Ian Rogers return ts.AddLocalReference<jobjectArray>(build_trace_visitor.GetInternalStackTrace()); 1131aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers} 1132aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers 113301158d7a57c8321370667a6045220237d16e0da8Elliott HughesjobjectArray Thread::InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal, 113401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobjectArray output_array, int* stack_depth) { 1135aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Transition into runnable state to work on Object*/Array* 1136aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers ScopedJniThreadState ts(env); 1137aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Decode the internal stack trace into the depth, method trace and PC trace 1138365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ObjectArray<Object>* method_trace = ts.Decode<ObjectArray<Object>*>(internal); 11399074b99bfbd5419e340f138a018b673ce71f77e8Ian Rogers int32_t depth = method_trace->GetLength() - 1; 1140aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth)); 1141aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers 1142aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1143aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers 114401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobjectArray result; 114501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes ObjectArray<StackTraceElement>* java_traces; 114601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes if (output_array != NULL) { 114701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Reuse the array we were given. 114801158d7a57c8321370667a6045220237d16e0da8Elliott Hughes result = output_array; 1149365c10235438607541fa2259a5fec48061b90bd8Ian Rogers java_traces = ts.Decode<ObjectArray<StackTraceElement>*>(output_array); 115001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // ...adjusting the number of frames we'll write to not exceed the array length. 115101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes depth = std::min(depth, java_traces->GetLength()); 115201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } else { 115301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Create java_trace array and place in local reference table 115401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes java_traces = class_linker->AllocStackTraceElementArray(depth); 115530646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (java_traces == NULL) { 115630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return NULL; 115730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1158365c10235438607541fa2259a5fec48061b90bd8Ian Rogers result = ts.AddLocalReference<jobjectArray>(java_traces); 115901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } 116001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 116101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes if (stack_depth != NULL) { 116201158d7a57c8321370667a6045220237d16e0da8Elliott Hughes *stack_depth = depth; 116301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } 116455df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 11656d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers MethodHelper mh; 11669b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao for (int32_t i = 0; i < depth; ++i) { 1167aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Prepare parameters for StackTraceElement(String cls, String method, String file, int line) 1168aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers Method* method = down_cast<Method*>(method_trace->Get(i)); 11696d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers mh.ChangeMethod(method); 11700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t dex_pc = pc_trace->Get(i); 11710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers int32_t line_number = mh.GetLineNumFromDexPC(dex_pc); 1172aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Allocate element, potentially triggering GC 117340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom // TODO: reuse class_name_object via Class::name_? 1174486013193c94b4321414c28ce9251911e14a0599Ian Rogers const char* descriptor = mh.GetDeclaringClassDescriptor(); 1175486013193c94b4321414c28ce9251911e14a0599Ian Rogers CHECK(descriptor != NULL); 1176486013193c94b4321414c28ce9251911e14a0599Ian Rogers std::string class_name(PrettyDescriptor(descriptor)); 117740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom SirtRef<String> class_name_object(String::AllocFromModifiedUtf8(class_name.c_str())); 117840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom if (class_name_object.get() == NULL) { 117940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom return NULL; 118040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom } 1181486013193c94b4321414c28ce9251911e14a0599Ian Rogers const char* method_name = mh.GetName(); 1182486013193c94b4321414c28ce9251911e14a0599Ian Rogers CHECK(method_name != NULL); 1183486013193c94b4321414c28ce9251911e14a0599Ian Rogers SirtRef<String> method_name_object(String::AllocFromModifiedUtf8(method_name)); 11846d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (method_name_object.get() == NULL) { 11856d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers return NULL; 11866d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 1187486013193c94b4321414c28ce9251911e14a0599Ian Rogers const char* source_file = mh.GetDeclaringClassSourceFile(); 1188486013193c94b4321414c28ce9251911e14a0599Ian Rogers SirtRef<String> source_name_object(String::AllocFromModifiedUtf8(source_file)); 118940381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom StackTraceElement* obj = StackTraceElement::Alloc(class_name_object.get(), 11906d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers method_name_object.get(), 11916d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers source_name_object.get(), 119240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom line_number); 119330646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (obj == NULL) { 119430646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return NULL; 119530646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1196aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers#ifdef MOVING_GARBAGE_COLLECTOR 1197aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Re-read after potential GC 1198aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers java_traces = Decode<ObjectArray<Object>*>(ts.Env(), result); 1199aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers method_trace = down_cast<ObjectArray<Object>*>(Decode<Object*>(ts.Env(), internal)); 1200aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers pc_trace = down_cast<IntArray*>(method_trace->Get(depth)); 1201aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers#endif 120255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao java_traces->Set(i, obj); 120355df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao } 1204aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers return result; 120555df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao} 120655df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 12075cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughesvoid Thread::ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...) { 1208a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_list args; 1209a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_start(args, fmt); 12104a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes ThrowNewExceptionV(exception_class_descriptor, fmt, args); 1211a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_end(args); 12124a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes} 12134a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes 12144a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughesvoid Thread::ThrowNewExceptionV(const char* exception_class_descriptor, const char* fmt, va_list ap) { 12154a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes std::string msg; 12164a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes StringAppendV(&msg, fmt, ap); 12175cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes ThrowNewException(exception_class_descriptor, msg.c_str()); 12185cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes} 121937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 12205cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughesvoid Thread::ThrowNewException(const char* exception_class_descriptor, const char* msg) { 1221a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes CHECK(!IsExceptionPending()); // Callers should either clear or call ThrowNewWrappedException. 1222a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes ThrowNewWrappedException(exception_class_descriptor, msg); 1223a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes} 1224a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 1225a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughesvoid Thread::ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg) { 1226e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes // Convert "Ljava/lang/Exception;" into JNI-style "java/lang/Exception". 12270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers CHECK_EQ('L', exception_class_descriptor[0]); 1228e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes std::string descriptor(exception_class_descriptor + 1); 12290cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers CHECK_EQ(';', descriptor[descriptor.length() - 1]); 1230e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes descriptor.erase(descriptor.length() - 1); 1231e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes 1232e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes JNIEnv* env = GetJniEnv(); 1233a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes jobject cause = env->ExceptionOccurred(); 1234a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes env->ExceptionClear(); 1235a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 1236726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes ScopedLocalRef<jclass> exception_class(env, env->FindClass(descriptor.c_str())); 123730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (exception_class.get() == NULL) { 123830646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI FindClass failed: " 123930646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes << PrettyTypeOf(GetException()); 124030646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes CHECK(IsExceptionPending()); 124130646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return; 124230646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1243ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom if (!Runtime::Current()->IsStarted()) { 1244ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom // Something is trying to throw an exception without a started 1245ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom // runtime, which is the common case in the compiler. We won't be 1246ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom // able to invoke the constructor of the exception, so use 1247ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom // AllocObject which will not invoke a constructor. 1248ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom ScopedLocalRef<jthrowable> exception( 1249ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom env, reinterpret_cast<jthrowable>(env->AllocObject(exception_class.get()))); 1250ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom if (exception.get() != NULL) { 1251ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom ScopedJniThreadState ts(env); 1252ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom Throwable* t = reinterpret_cast<Throwable*>(ts.Self()->DecodeJObject(exception.get())); 125302fbef0e356ca43b2032044f870d59de4a4ae92aIan Rogers t->SetDetailMessage(String::AllocFromModifiedUtf8(msg)); 1254ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom ts.Self()->SetException(t); 1255ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } else { 1256ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI AllocObject failed: " 1257ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom << PrettyTypeOf(GetException()); 1258ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom CHECK(IsExceptionPending()); 1259ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } 1260ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom return; 1261ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } 1262a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes int rc = ::art::ThrowNewException(env, exception_class.get(), msg, cause); 126330646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (rc != JNI_OK) { 126430646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI ThrowNew failed: " 126530646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes << PrettyTypeOf(GetException()); 126630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes CHECK(IsExceptionPending()); 126730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1268a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes} 1269a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes 12702ced6a534157d5d963693346904389c19775d2daElliott Hughesvoid Thread::ThrowOutOfMemoryError(const char* msg) { 12712ced6a534157d5d963693346904389c19775d2daElliott Hughes LOG(ERROR) << StringPrintf("Throwing OutOfMemoryError \"%s\"%s", 12722ced6a534157d5d963693346904389c19775d2daElliott Hughes msg, (throwing_OutOfMemoryError_ ? " (recursive case)" : "")); 1273726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes if (!throwing_OutOfMemoryError_) { 1274726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes throwing_OutOfMemoryError_ = true; 127557aba86f29d7e795bf7e68c65cc464d2291b6af1Elliott Hughes ThrowNewException("Ljava/lang/OutOfMemoryError;", msg); 1276418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes } else { 1277225f5a1df25241babd16cdba54056b9e2cd166a2Elliott Hughes Dump(LOG(ERROR)); // The pre-allocated OOME has no stack, so help out and log one. 1278225f5a1df25241babd16cdba54056b9e2cd166a2Elliott Hughes SetException(Runtime::Current()->GetPreAllocatedOutOfMemoryError()); 1279418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes } 1280726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes throwing_OutOfMemoryError_ = false; 128179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes} 128279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 1283498508c1187dc07d3eae5476784cde20f5224d93Elliott HughesThread* Thread::CurrentFromGdb() { 1284accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes return Thread::Current(); 1285accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes} 1286accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1287accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughesvoid Thread::DumpFromGdb() const { 12886b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom std::ostringstream ss; 12896b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom Dump(ss); 1290955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string str(ss.str()); 12916b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom // log to stderr for debugging command line processes 12926b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom std::cerr << str; 12936b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom#ifdef HAVE_ANDROID_OS 12946b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom // log to logcat for debugging frameworks processes 12956b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom LOG(INFO) << str; 12966b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom#endif 1297accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes} 1298accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 129998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughesstruct EntryPointInfo { 130098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes uint32_t offset; 130198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes const char* name; 130298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes}; 130398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes#define ENTRY_POINT_INFO(x) { ENTRYPOINT_OFFSET(x), #x } 130498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughesstatic const EntryPointInfo gThreadEntryPointInfo[] = { 130598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pAllocArrayFromCode), 130698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pAllocArrayFromCodeWithAccessCheck), 130798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pAllocObjectFromCode), 130898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pAllocObjectFromCodeWithAccessCheck), 130998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCheckAndAllocArrayFromCode), 131098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCheckAndAllocArrayFromCodeWithAccessCheck), 131198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInstanceofNonTrivialFromCode), 131298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCanPutArrayElementFromCode), 131398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCheckCastFromCode), 131498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDebugMe), 131598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pUpdateDebuggerFromCode), 131698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInitializeStaticStorage), 131798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInitializeTypeAndVerifyAccessFromCode), 131898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInitializeTypeFromCode), 131998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pResolveStringFromCode), 132098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSet32Instance), 132198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSet32Static), 132298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSet64Instance), 132398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSet64Static), 132498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSetObjInstance), 132598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pSetObjStatic), 132698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGet32Instance), 132798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGet32Static), 132898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGet64Instance), 132998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGet64Static), 133098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGetObjInstance), 133198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pGetObjStatic), 133298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pHandleFillArrayDataFromCode), 133398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDecodeJObjectInThread), 133498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFindNativeMethod), 133598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pLockObjectFromCode), 133698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pUnlockObjectFromCode), 133798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCmpgDouble), 133898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCmpgFloat), 133998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCmplDouble), 134098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCmplFloat), 134198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDadd), 134298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDdiv), 134398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDmul), 134498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDsub), 134598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pF2d), 134698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFmod), 134798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pI2d), 134898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pL2d), 134998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pD2f), 135098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFadd), 135198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFdiv), 135298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFmodf), 135398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFmul), 135498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pFsub), 135598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pI2f), 135698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pL2f), 135798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pD2iz), 135898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pF2iz), 135998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pIdivmod), 136098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pD2l), 136198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pF2l), 136298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pLdiv), 136398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pLdivmod), 136498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pLmul), 136598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pShlLong), 136698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pShrLong), 136798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pUshrLong), 136898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pIndexOf), 136998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pMemcmp16), 137098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pStringCompareTo), 137198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pMemcpy), 137298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pUnresolvedDirectMethodTrampolineFromCode), 137398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeDirectTrampolineWithAccessCheck), 137498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeInterfaceTrampoline), 137598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeInterfaceTrampolineWithAccessCheck), 137698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeStaticTrampolineWithAccessCheck), 137798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeSuperTrampolineWithAccessCheck), 137898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pInvokeVirtualTrampolineWithAccessCheck), 137998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pCheckSuspendFromCode), 138098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pTestSuspendFromCode), 138198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pDeliverException), 138298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowAbstractMethodErrorFromCode), 138398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowArrayBoundsFromCode), 138498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowDivZeroFromCode), 138598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowNoSuchMethodFromCode), 138698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowNullPointerFromCode), 138798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowStackOverflowFromCode), 138898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes ENTRY_POINT_INFO(pThrowVerificationErrorFromCode), 138998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes}; 139098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes#undef ENTRY_POINT_INFO 139198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes 139228fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughesvoid Thread::DumpThreadOffset(std::ostream& os, uint32_t offset, size_t size_of_pointers) { 139328fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes CHECK_EQ(size_of_pointers, 4U); // TODO: support 64-bit targets. 139498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes 139598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes#define DO_THREAD_OFFSET(x) if (offset == static_cast<uint32_t>(OFFSETOF_VOLATILE_MEMBER(Thread, x))) { os << # x; return; } 139698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(card_table_); 139798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(exception_); 139898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(jni_env_); 139998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(self_); 140098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(stack_end_); 140198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(state_); 140298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(suspend_count_); 140398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(thin_lock_id_); 14040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers //DO_THREAD_OFFSET(top_of_managed_stack_); 14050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers //DO_THREAD_OFFSET(top_of_managed_stack_pc_); 140698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes DO_THREAD_OFFSET(top_sirt_); 140728fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes#undef DO_THREAD_OFFSET 140898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes 140998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes size_t entry_point_count = arraysize(gThreadEntryPointInfo); 141098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes CHECK_EQ(entry_point_count * size_of_pointers, sizeof(EntryPoints)); 141198e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes uint32_t expected_offset = OFFSETOF_MEMBER(Thread, entrypoints_); 141298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes for (size_t i = 0; i < entry_point_count; ++i) { 141398e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes CHECK_EQ(gThreadEntryPointInfo[i].offset, expected_offset); 141498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes expected_offset += size_of_pointers; 141598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes if (gThreadEntryPointInfo[i].offset == offset) { 141698e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes os << gThreadEntryPointInfo[i].name; 141798e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes return; 141898e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes } 141998e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes } 142098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes os << offset; 142128fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes} 142228fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes 14230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersstatic const bool kDebugExceptionDelivery = false; 14240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass CatchBlockStackVisitor : public StackVisitor { 1425bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers public: 14260399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CatchBlockStackVisitor(Thread* self, Throwable* exception) 14270399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers : StackVisitor(self->GetManagedStack(), self->GetTraceStack(), self->GetLongJumpContext()), 14280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self_(self), exception_(exception), to_find_(exception->GetClass()), throw_method_(NULL), 14290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers throw_frame_id_(0), throw_dex_pc_(0), handler_quick_frame_(NULL), 14300399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_quick_frame_pc_(0), handler_dex_pc_(0), native_method_count_(0), 143157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers method_tracing_active_(Runtime::Current()->IsMethodTracingActive()) { 14320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self->StartAssertNoThreadSuspension(); // Exception not in root sets, can't allow GC. 143367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers } 1434bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 14350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool VisitFrame() { 14360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* method = GetMethod(); 1437530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes if (method == NULL) { 14380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // This is the upcall, we remember the frame and last pc so that we may long jump to them. 14390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_quick_frame_pc_ = GetCurrentQuickFramePc(); 14400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_quick_frame_ = GetCurrentQuickFrame(); 144157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers return false; // End stack walk. 1442530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes } 1443530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes uint32_t dex_pc = DexFile::kDexNoIndex; 144457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers if (method->IsRuntimeMethod()) { 1445530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes // ignore callee save method 144657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers DCHECK(method->IsCalleeSaveMethod()); 1447530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes } else { 14480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (throw_method_ == NULL) { 14490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers throw_method_ = method; 14500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers throw_frame_id_ = GetFrameId(); 14510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers throw_dex_pc_ = GetDexPc(); 14520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 14530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (method->IsNative()) { 14540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers native_method_count_++; 14550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 14560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Unwind stack when an exception occurs during method tracing 14570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (UNLIKELY(method_tracing_active_ && IsTraceExitPc(GetCurrentQuickFramePc()))) { 14580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uintptr_t pc = AdjustQuickFramePcForDexPcComputation(TraceMethodUnwindFromCode(Thread::Current())); 14590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dex_pc = method->ToDexPC(pc); 14600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 14610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dex_pc = GetDexPc(); 1462530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes } 1463bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 1464530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes } 1465530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes if (dex_pc != DexFile::kDexNoIndex) { 1466530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes uint32_t found_dex_pc = method->FindCatchBlock(to_find_, dex_pc); 1467530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes if (found_dex_pc != DexFile::kDexNoIndex) { 14680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_dex_pc_ = found_dex_pc; 14690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_quick_frame_pc_ = method->ToNativePC(found_dex_pc); 14700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers handler_quick_frame_ = GetCurrentQuickFrame(); 147157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers return false; // End stack walk. 1472bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 14731a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 147457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers return true; // Continue stack walk. 14751a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 14761a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 14770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void DoLongJump() { 14780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* catch_method = *handler_quick_frame_; 14796e9d22c78c1016e70f8c2a9e6bc66c94ec36f728Elliott Hughes Dbg::PostException(self_, throw_frame_id_, throw_method_, throw_dex_pc_, 14800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers catch_method, handler_dex_pc_, exception_); 14810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (kDebugExceptionDelivery) { 14820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (catch_method == NULL) { 14830399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers LOG(INFO) << "Handler is upcall"; 14840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 14850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 14860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const DexFile& dex_file = 14870399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers class_linker->FindDexFile(catch_method->GetDeclaringClass()->GetDexCache()); 14880399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers int line_number = dex_file.GetLineNumFromPC(catch_method, handler_dex_pc_); 14890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers LOG(INFO) << "Handler: " << PrettyMethod(catch_method) << " (line: " << line_number << ")"; 14900399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 14910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 14920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self_->SetException(exception_); 14930399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self_->EndAssertNoThreadSuspension(); // Exception back in root set. 14940399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Place context back on thread so it will be available when we continue. 14950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers self_->ReleaseLongJumpContext(context_); 14960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers context_->SetSP(reinterpret_cast<uintptr_t>(handler_quick_frame_)); 14970399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CHECK_NE(handler_quick_frame_pc_, 0u); 14980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers context_->SetPC(handler_quick_frame_pc_); 14990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers context_->SmashCallerSaves(); 15000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers context_->DoLongJump(); 15010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 15020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 15030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers private: 15040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Thread* self_; 15050399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Throwable* exception_; 15060399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // The type of the exception catch block to find. 1507bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Class* to_find_; 15080399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* throw_method_; 15090399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers JDWP::FrameId throw_frame_id_; 15100399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t throw_dex_pc_; 15110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Quick frame with found handler or last frame if no handler found. 15120399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method** handler_quick_frame_; 15130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // PC to branch to for the handler. 15140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uintptr_t handler_quick_frame_pc_; 15150399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Associated dex PC. 15160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t handler_dex_pc_; 151767375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers // Number of native methods passed in crawl (equates to number of SIRTs to pop) 151867375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers uint32_t native_method_count_; 151957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers // Is method tracing active? 152057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers const bool method_tracing_active_; 1521bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers}; 1522bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1523ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogersvoid Thread::DeliverException() { 1524d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes Throwable* exception = GetException(); // Get exception from thread 1525ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers CHECK(exception != NULL); 152628ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers // Don't leave exception visible while we try to find the handler, which may cause class 1527d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes // resolution. 152828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers ClearException(); 152928ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (kDebugExceptionDelivery) { 1530a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers String* msg = exception->GetDetailMessage(); 1531a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers std::string str_msg(msg != NULL ? msg->ToModifiedUtf8() : ""); 1532a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers DumpStack(LOG(INFO) << "Delivering exception: " << PrettyTypeOf(exception) 1533c073b075241640c94c27e661ed6f29ff5fcee5d8Elliott Hughes << ": " << str_msg << "\n"); 153428ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 15350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CatchBlockStackVisitor catch_finder(this, exception); 15360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers catch_finder.WalkStack(true); 15370399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers catch_finder.DoLongJump(); 15389a8a8889418e09bf2d4ae3f683fbb40a71c3c8f4Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1539bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 1540bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1541bdb0391258abc54bf77c676e36847d28a783bfe5Ian RogersContext* Thread::GetLongJumpContext() { 154285d1545e985ac689db4bad7849880e843707c862Elliott Hughes Context* result = long_jump_context_; 1543bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers if (result == NULL) { 1544bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers result = Context::Create(); 15450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 15460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers long_jump_context_ = NULL; // Avoid context being shared. 15471a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 1548bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers return result; 15491a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao} 15501a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 15510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian RogersMethod* Thread::GetCurrentMethod(uint32_t* dex_pc, size_t* frame_id) const { 15520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers struct CurrentMethodVisitor : public StackVisitor { 15530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CurrentMethodVisitor(const ManagedStack* stack, 15540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const std::vector<TraceStackFrame>* trace_stack) : 15550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers StackVisitor(stack, trace_stack), method_(NULL), dex_pc_(0), frame_id_(0) {} 15568be2d40d42223b515de12629216151a558895969Elliott Hughes 15570399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers virtual bool VisitFrame() { 15580399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* m = GetMethod(); 15590399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (m->IsRuntimeMethod()) { 15600399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Continue if this is a runtime method. 15610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return true; 15620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 15630399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers method_ = m; 15640399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers dex_pc_ = GetDexPc(); 15650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers frame_id_ = GetFrameId(); 15660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return false; 15670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 15680399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* method_; 15690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t dex_pc_; 15700399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t frame_id_; 15710399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers }; 15720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 15730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CurrentMethodVisitor visitor(GetManagedStack(), GetTraceStack()); 15740399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers visitor.WalkStack(false); 15750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (dex_pc != NULL) { 15760399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers *dex_pc = visitor.dex_pc_; 1577d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes } 15780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (frame_id != NULL) { 15790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers *frame_id = visitor.frame_id_; 1580ee0d3fb2fbd736484fe8c3177a4e965ea86d1c65TDYa } 15810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return visitor.method_; 1582ee0d3fb2fbd736484fe8c3177a4e965ea86d1c65TDYa} 158333dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao 15845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesbool Thread::HoldsLock(Object* object) { 15855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (object == NULL) { 15865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return false; 15875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 158824a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstrom return object->GetThinLockId() == thin_lock_id_; 15895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 15905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1591038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughesbool Thread::IsDaemon() { 1592365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ScopedJniThreadState ts(this); 1593365c10235438607541fa2259a5fec48061b90bd8Ian Rogers return ts.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->GetBoolean(peer_); 1594038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes} 1595038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes 15960399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass ReferenceMapVisitor : public StackVisitor { 1597d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers public: 15980399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ReferenceMapVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack, 15990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Context* context, Heap::RootVisitor* root_visitor, 16000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers void* arg) : StackVisitor(stack, trace_stack, context), 16010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers root_visitor_(root_visitor), arg_(arg) { 1602d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1603d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 16040399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers bool VisitFrame() { 16056a4be3a6226cec645cf905dd352e44f7968a7fa4Brian Carlstrom if (false) { 16060399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers LOG(INFO) << "Visiting stack roots in " << PrettyMethod(GetMethod()) 16070399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers << StringPrintf("@ PC:%04x", GetDexPc()); 16086a4be3a6226cec645cf905dd352e44f7968a7fa4Brian Carlstrom } 16090399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ShadowFrame* shadow_frame = GetCurrentShadowFrame(); 16100399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (shadow_frame != NULL) { 16110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers shadow_frame->VisitRoots(root_visitor_, arg_); 16120399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 16130399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Method* m = GetMethod(); 16140399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Process register map (which native and runtime methods don't have) 1615640495bd1aebcd0b429d59f62b57d0c984b2d8c6Ian Rogers if (!m->IsNative() && !m->IsRuntimeMethod() && !m->IsProxyMethod()) { 16160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const uint8_t* gc_map = m->GetGcMap(); 16170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CHECK(gc_map != NULL) << PrettyMethod(m); 16180399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t gc_map_length = m->GetGcMapLength(); 16190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CHECK_NE(0U, gc_map_length) << PrettyMethod(m); 16200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers verifier::PcToReferenceMap map(gc_map, gc_map_length); 16210399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const uint8_t* reg_bitmap = map.FindBitMap(GetDexPc()); 16220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CHECK(reg_bitmap != NULL); 16230399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const VmapTable vmap_table(m->GetVmapTableRaw()); 16240399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem(); 16250399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers DCHECK(code_item != NULL); // can't be NULL or how would we compile its instructions? 16260399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t core_spills = m->GetCoreSpillMask(); 16270399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t fp_spills = m->GetFpSpillMask(); 16280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t frame_size = m->GetFrameSizeInBytes(); 16290399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // For all dex registers in the bitmap 16300399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers size_t num_regs = std::min(map.RegWidth() * 8, 16310399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers static_cast<size_t>(code_item->registers_size_)); 16320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers for (size_t reg = 0; reg < num_regs; ++reg) { 16330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Does this register hold a reference? 16340399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (TestBitmap(reg, reg_bitmap)) { 16350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t vmap_offset; 16360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Object* ref; 16370399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (vmap_table.IsInContext(reg, vmap_offset)) { 16380399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Compute the register we need to load from the context 16390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t spill_mask = core_spills; 16400399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers CHECK_LT(vmap_offset, static_cast<uint32_t>(__builtin_popcount(spill_mask))); 16410399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t matches = 0; 16420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers uint32_t spill_shifts = 0; 16430399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers while (matches != (vmap_offset + 1)) { 16440399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers DCHECK_NE(spill_mask, 0u); 16450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers matches += spill_mask & 1; // Add 1 if the low bit is set 16460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers spill_mask >>= 1; 16470399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers spill_shifts++; 16480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 16490399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers spill_shifts--; // wind back one as we want the last match 16500399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ref = reinterpret_cast<Object*>(GetGPR(spill_shifts)); 16510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 16520399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ref = reinterpret_cast<Object*>(GetVReg(code_item, core_spills, fp_spills, 16530399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers frame_size, reg)); 16540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 16550399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (ref != NULL) { 16560399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers root_visitor_(ref, arg_); 1657d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 16584f894e385e8ac018f078be75fea0a45696626b15Shih-wei Liao } 1659d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1660d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1661d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1662530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 1663d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1664d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 1665d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers private: 1666d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers bool TestBitmap(int reg, const uint8_t* reg_vector) { 1667d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers return ((reg_vector[reg / 8] >> (reg % 8)) & 0x01) != 0; 1668d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 1669d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 1670d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers // Call-back when we visit a root 1671d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers Heap::RootVisitor* root_visitor_; 1672d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers // Argument to call-back 1673d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers void* arg_; 1674d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers}; 1675d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 1676d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogersvoid Thread::VisitRoots(Heap::RootVisitor* visitor, void* arg) { 1677d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes if (exception_ != NULL) { 1678d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes visitor(exception_, arg); 1679d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 1680d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes if (peer_ != NULL) { 1681d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes visitor(peer_, arg); 1682d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 168340381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom if (class_loader_override_ != NULL) { 168440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom visitor(class_loader_override_, arg); 168540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom } 1686410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes jni_env_->locals.VisitRoots(visitor, arg); 1687410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes jni_env_->monitors.VisitRoots(visitor, arg); 16888dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao 16898dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao SirtVisitRoots(visitor, arg); 16908dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao 1691d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers // Visit roots on this thread's stack 16920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Context* context = GetLongJumpContext(); 16930399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ReferenceMapVisitor mapper(GetManagedStack(), GetTraceStack(), context, visitor, arg); 16940399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers mapper.WalkStack(); 16950399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ReleaseLongJumpContext(context); 1696410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes} 1697410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 1698250455229aa0cc07bbd18174efe510bd52631a99jeffhao#if VERIFY_OBJECT_ENABLED 16990399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersstatic void VerifyObject(const Object* obj, void* arg) { 17000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Heap* heap = reinterpret_cast<Heap*>(arg); 17010399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers heap->VerifyObject(obj); 1702250455229aa0cc07bbd18174efe510bd52631a99jeffhao} 1703250455229aa0cc07bbd18174efe510bd52631a99jeffhao 1704250455229aa0cc07bbd18174efe510bd52631a99jeffhaovoid Thread::VerifyStack() { 1705e66ac79b90a12b01b9d67ee9f7f586e638e67fabjeffhao UniquePtr<Context> context(Context::Create()); 17060399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ReferenceMapVisitor mapper(GetManagedStack(), context.get(), VerifyObject, 17070399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Runtime::Current()->GetHeap()); 17080399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers mapper.WalkStack(); 1709250455229aa0cc07bbd18174efe510bd52631a99jeffhao} 1710250455229aa0cc07bbd18174efe510bd52631a99jeffhao#endif 1711250455229aa0cc07bbd18174efe510bd52631a99jeffhao 1712330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread) { 1713899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes thread.Dump(os, false); 1714330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes return os; 1715330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes} 1716330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes 1717a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughesvoid Thread::CheckSafeToLockOrUnlock(MutexRank rank, bool is_locking) { 171817057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes if (this == NULL) { 171917057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes CHECK(Runtime::Current()->IsShuttingDown()); 172017057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes return; 172117057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes } 1722ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes if (is_locking) { 1723ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes if (held_mutexes_[rank] == 0) { 1724ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes bool bad_mutexes_held = false; 1725ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes for (int i = kMaxMutexRank; i > rank; --i) { 1726ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes if (held_mutexes_[i] != 0) { 1727ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes LOG(ERROR) << "holding " << static_cast<MutexRank>(i) << " while " << (is_locking ? "locking" : "unlocking") << " " << rank; 1728ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes bad_mutexes_held = true; 1729ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } 1730ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } 1731b5db3bb5b17f2bb42f3c62408938f4bf939f8a39Elliott Hughes CHECK(!bad_mutexes_held) << rank; 1732ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } 1733ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes ++held_mutexes_[rank]; 1734ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } else { 1735b5db3bb5b17f2bb42f3c62408938f4bf939f8a39Elliott Hughes CHECK_GT(held_mutexes_[rank], 0U) << rank; 1736ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes --held_mutexes_[rank]; 1737ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes } 1738ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes} 1739ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 1740a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughesvoid Thread::CheckSafeToWait(MutexRank rank) { 174117057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes if (this == NULL) { 174217057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes CHECK(Runtime::Current()->IsShuttingDown()); 174317057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes return; 174417057b15cb8d8da97b2bc28fd38bdcc7a34e846eElliott Hughes } 1745a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes bool bad_mutexes_held = false; 1746a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes for (int i = kMaxMutexRank; i >= 0; --i) { 1747a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes if (i != rank && held_mutexes_[i] != 0) { 1748a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes LOG(ERROR) << "holding " << static_cast<MutexRank>(i) << " while doing condition variable wait on " << rank; 1749a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes bad_mutexes_held = true; 1750a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes } 1751a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes } 1752a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes if (held_mutexes_[rank] == 0) { 1753a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes LOG(ERROR) << "*not* holding " << rank << " while doing condition variable wait on it"; 1754a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes bad_mutexes_held = true; 1755a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes } 1756a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes CHECK(!bad_mutexes_held); 1757a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes} 1758a4060e5fe4729fa30bde965efc35779690478fa4Elliott Hughes 17598daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes} // namespace art 1760