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 17752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier#define ATRACE_TAG ATRACE_TAG_DALVIK 18752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier 19578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 20b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 21752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier#include <cutils/trace.h> 22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <pthread.h> 232acf36d8cfeb5ddb293904148aa70f25ef6d8845Elliott Hughes#include <signal.h> 24dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom#include <sys/resource.h> 25dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom#include <sys/time.h> 26a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <algorithm> 28dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes#include <bitset> 29eb4f614f2eb53b92ebd416fa418f550861655887Elliott Hughes#include <cerrno> 30a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <iostream> 31b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <list> 32c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers#include <sstream> 33b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 34166db04e259ca51838c311891598664deeed85adIan Rogers#include "arch/context.h" 35c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 363d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h" 3741b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "base/bit_utils.h" 3876b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h" 392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "base/timing_logger.h" 40c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers#include "base/to_str.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker-inl.h" 4246e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes#include "debugger.h" 434f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 447655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "entrypoints/entrypoint_utils.h" 45d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier#include "entrypoints/quick/quick_alloc_entrypoints.h" 460c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h" 471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h" 48e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "gc/allocator/rosalloc.h" 491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/heap.h" 501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/space.h" 5122d5e735f403c57525fe868304c7123f0ce66399Ian Rogers#include "handle_scope-inl.h" 52c56057e40938c587a74984651a510e320a8cb4fdMathieu Chartier#include "indirect_reference_table-inl.h" 53c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes#include "jni_internal.h" 542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 5522d5e735f403c57525fe868304c7123f0ce66399Ian Rogers#include "mirror/class-inl.h" 562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/stack_trace_element.h" 588e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes#include "monitor.h" 5922d5e735f403c57525fe868304c7123f0ce66399Ian Rogers#include "object_lock.h" 60fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz#include "quick_exception_handler.h" 617624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "quick/quick_method_frame_info.h" 629a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson#include "reflection.h" 63578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "runtime.h" 6400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 6546e251bf7200cc06f5a9a82ee2030e650f5e1443Elliott Hughes#include "ScopedLocalRef.h" 663c539ffccabada93c404c0dfba8b52926ae06d0cAnwar Ghuloum#include "ScopedUtfChars.h" 6768e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes#include "stack.h" 688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread_list.h" 6922d5e735f403c57525fe868304c7123f0ce66399Ian Rogers#include "thread-inl.h" 70a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include "utils.h" 71ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa#include "verifier/dex_gc_map.h" 7212d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier#include "verifier/method_verifier.h" 734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier#include "verify_object-inl.h" 741809a72a66d245ae598582d658b93a24ac3bf01eIan Rogers#include "vmap_table.h" 75eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h" 76b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 77b557353b22c728eecbd1c68593b482622c7782a8Carl Shapironamespace art { 78b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 790878d654e7be8c9666579e22522704d8887415ccIan Rogersbool Thread::is_started_ = false; 80b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiropthread_key_t Thread::pthread_key_self_; 810aded089f565008ba5908e395e5914ca4f91f2deDave AllisonConditionVariable* Thread::resume_cond_ = nullptr; 82648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allisonconst size_t Thread::kStackOverflowImplicitCheckSize = GetStackOverflowReservedBytes(kRuntimeISA); 83b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 847dc5166ea740359d381097a7ab382c1dd404055fElliott Hughesstatic const char* kThreadNameDuringStartup = "<native thread without managed peer>"; 857dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes 865d76c435082332ef79a22962386fa92a0870e378Ian Rogersvoid Thread::InitCardTable() { 87dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.card_table = Runtime::Current()->GetHeap()->GetCardTable()->GetBiasedBegin(); 885d76c435082332ef79a22962386fa92a0870e378Ian Rogers} 895d76c435082332ef79a22962386fa92a0870e378Ian Rogers 903ea0f42467790809fcfc9fc861605d465808090fElliott Hughesstatic void UnimplementedEntryPoint() { 913ea0f42467790809fcfc9fc861605d465808090fElliott Hughes UNIMPLEMENTED(FATAL); 923ea0f42467790809fcfc9fc861605d465808090fElliott Hughes} 933ea0f42467790809fcfc9fc861605d465808090fElliott Hughes 94848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogersvoid InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, 95956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes QuickEntryPoints* qpoints); 967655f29fabc0a12765de828914a18314382e5a35Ian Rogers 97848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogersvoid Thread::InitTlsEntryPoints() { 983ea0f42467790809fcfc9fc861605d465808090fElliott Hughes // Insert a placeholder so we can easily tell if we call an unimplemented entry point. 99dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers uintptr_t* begin = reinterpret_cast<uintptr_t*>(&tlsPtr_.interpreter_entrypoints); 100acbb30867482986e02a7cc53c099b8d56d32aceeXingxing Pan uintptr_t* end = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(&tlsPtr_.quick_entrypoints) + 101acbb30867482986e02a7cc53c099b8d56d32aceeXingxing Pan sizeof(tlsPtr_.quick_entrypoints)); 1027655f29fabc0a12765de828914a18314382e5a35Ian Rogers for (uintptr_t* it = begin; it != end; ++it) { 1037655f29fabc0a12765de828914a18314382e5a35Ian Rogers *it = reinterpret_cast<uintptr_t>(UnimplementedEntryPoint); 1047655f29fabc0a12765de828914a18314382e5a35Ian Rogers } 105dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers InitEntryPoints(&tlsPtr_.interpreter_entrypoints, &tlsPtr_.jni_entrypoints, 106956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes &tlsPtr_.quick_entrypoints); 107c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes} 108c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes 109848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haovoid Thread::InitStringEntryPoints() { 110848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedObjectAccess soa(this); 111848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QuickEntryPoints* qpoints = &tlsPtr_.quick_entrypoints; 112848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewEmptyString = reinterpret_cast<void(*)()>( 113848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newEmptyString)); 114848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_B = reinterpret_cast<void(*)()>( 115848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_B)); 116848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BI = reinterpret_cast<void(*)()>( 117848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BI)); 118848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BII = reinterpret_cast<void(*)()>( 119848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BII)); 120848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BIII = reinterpret_cast<void(*)()>( 121848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIII)); 122848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BIIString = reinterpret_cast<void(*)()>( 123848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIIString)); 124848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BString = reinterpret_cast<void(*)()>( 125848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BString)); 126848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BIICharset = reinterpret_cast<void(*)()>( 127848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BIICharset)); 128848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromBytes_BCharset = reinterpret_cast<void(*)()>( 129848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromBytes_BCharset)); 130848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromChars_C = reinterpret_cast<void(*)()>( 131848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_C)); 132848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromChars_CII = reinterpret_cast<void(*)()>( 133848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_CII)); 134848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromChars_IIC = reinterpret_cast<void(*)()>( 135848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromChars_IIC)); 136848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromCodePoints = reinterpret_cast<void(*)()>( 137848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromCodePoints)); 138848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromString = reinterpret_cast<void(*)()>( 139848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromString)); 140848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromStringBuffer = reinterpret_cast<void(*)()>( 141848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromStringBuffer)); 142848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pNewStringFromStringBuilder = reinterpret_cast<void(*)()>( 143848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao soa.DecodeMethod(WellKnownClasses::java_lang_StringFactory_newStringFromStringBuilder)); 144848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 145848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 1463b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchivoid Thread::ResetQuickAllocEntryPointsForThread() { 147dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ResetQuickAllocEntryPoints(&tlsPtr_.quick_entrypoints); 1483b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi} 1493b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 150bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertzclass DeoptimizationReturnValueRecord { 151bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz public: 152bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DeoptimizationReturnValueRecord(const JValue& ret_val, 153bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz bool is_reference, 154bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DeoptimizationReturnValueRecord* link) 155bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz : ret_val_(ret_val), is_reference_(is_reference), link_(link) {} 156bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 157bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz JValue GetReturnValue() const { return ret_val_; } 158bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz bool IsReference() const { return is_reference_; } 159bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DeoptimizationReturnValueRecord* GetLink() const { return link_; } 160bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz mirror::Object** GetGCRoot() { 161bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DCHECK(is_reference_); 162bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz return ret_val_.GetGCRoot(); 163bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz } 164bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 165bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz private: 166bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz JValue ret_val_; 167bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz const bool is_reference_; 168bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DeoptimizationReturnValueRecord* const link_; 169bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 170bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DISALLOW_COPY_AND_ASSIGN(DeoptimizationReturnValueRecord); 171bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz}; 172bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 173bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertzclass StackedShadowFrameRecord { 174bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz public: 175bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameRecord(ShadowFrame* shadow_frame, 176bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameType type, 177bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameRecord* link) 178bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz : shadow_frame_(shadow_frame), 179bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz type_(type), 180bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz link_(link) {} 181bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 182bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz ShadowFrame* GetShadowFrame() const { return shadow_frame_; } 183bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameType GetType() const { return type_; } 184bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameRecord* GetLink() const { return link_; } 185bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 186bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz private: 187bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz ShadowFrame* const shadow_frame_; 188bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz const StackedShadowFrameType type_; 189bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz StackedShadowFrameRecord* const link_; 190bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 191bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DISALLOW_COPY_AND_ASSIGN(StackedShadowFrameRecord); 192bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz}; 193bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz 194ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yangvoid Thread::PushAndClearDeoptimizationReturnValue() { 195ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang DeoptimizationReturnValueRecord* record = new DeoptimizationReturnValueRecord( 196ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tls64_.deoptimization_return_value, 197ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tls32_.deoptimization_return_value_is_reference, 198ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tlsPtr_.deoptimization_return_value_stack); 199ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tlsPtr_.deoptimization_return_value_stack = record; 200ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang ClearDeoptimizationReturnValue(); 2013ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee} 2023ea4ec5629613013ad9b0d7a69abdb94491ac46fbuzbee 203ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao YangJValue Thread::PopDeoptimizationReturnValue() { 204ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang DeoptimizationReturnValueRecord* record = tlsPtr_.deoptimization_return_value_stack; 205ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang DCHECK(record != nullptr); 206ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tlsPtr_.deoptimization_return_value_stack = record->GetLink(); 207ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang JValue ret_val(record->GetReturnValue()); 208ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang delete record; 209ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang return ret_val; 210306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers} 211306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers 212ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yangvoid Thread::PushStackedShadowFrame(ShadowFrame* sf, StackedShadowFrameType type) { 213ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang StackedShadowFrameRecord* record = new StackedShadowFrameRecord( 214ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang sf, type, tlsPtr_.stacked_shadow_frame_record); 215ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tlsPtr_.stacked_shadow_frame_record = record; 216306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers} 217306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers 218ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao YangShadowFrame* Thread::PopStackedShadowFrame(StackedShadowFrameType type) { 219ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang StackedShadowFrameRecord* record = tlsPtr_.stacked_shadow_frame_record; 220ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang DCHECK(record != nullptr); 221bf1fa2ccb5e7409910b99dc46b616e44c66ade68Sebastien Hertz DCHECK_EQ(record->GetType(), type); 222ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang tlsPtr_.stacked_shadow_frame_record = record->GetLink(); 223ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang ShadowFrame* shadow_frame = record->GetShadowFrame(); 224ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang delete record; 225ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang return shadow_frame; 2262a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe} 2272a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe 228caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Thread::InitTid() { 229dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.tid = ::art::GetTid(); 230caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 231caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 232caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Thread::InitAfterFork() { 2338029cbe626a467b344ff84d86170d757aa12ecd4Elliott Hughes // One thread (us) survived the fork, but we have a new tid so we need to 2348029cbe626a467b344ff84d86170d757aa12ecd4Elliott Hughes // update the value stashed in this Thread*. 235caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom InitTid(); 236caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 237caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 23878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromvoid* Thread::CreateCallback(void* arg) { 23993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes Thread* self = reinterpret_cast<Thread*>(arg); 240120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime* runtime = Runtime::Current(); 2410aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (runtime == nullptr) { 242120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOG(ERROR) << "Thread attaching to non-existent runtime: " << *self; 2430aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 244120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 245120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers { 24650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers // TODO: pass self to MutexLock - requires self to equal Thread::Current(), which is only true 24750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers // after self->Init(). 2480aded089f565008ba5908e395e5914ca4f91f2deDave Allison MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_); 249120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // Check that if we got here we cannot be shutting down (as shutdown should never have started 250120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // while threads are being born). 251590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier CHECK(!runtime->IsShuttingDownLocked()); 252520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // Note: given that the JNIEnv is created in the parent thread, the only failure point here is 253520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // a mess in InitStackHwm. We do not have a reasonable way to recover from that, so abort 254520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // the runtime in such a case. In case this ever changes, we need to make sure here to 255520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // delete the tmp_jni_env, as we own it at this point. 256520abbd0edcf333f07164539620ce65258c72383Andreas Gampe CHECK(self->Init(runtime->GetThreadList(), runtime->GetJavaVM(), self->tlsPtr_.tmp_jni_env)); 257520abbd0edcf333f07164539620ce65258c72383Andreas Gampe self->tlsPtr_.tmp_jni_env = nullptr; 258120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime::Current()->EndThreadBirth(); 259120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 26047179f76e3f03fe3eb21dfb081d50733ca316371Elliott Hughes { 26100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(self); 262848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao self->InitStringEntryPoints(); 263cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers 264cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers // Copy peer into self, deleting global reference when done. 265dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(self->tlsPtr_.jpeer != nullptr); 266dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers self->tlsPtr_.opeer = soa.Decode<mirror::Object*>(self->tlsPtr_.jpeer); 267dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers self->GetJniEnv()->DeleteGlobalRef(self->tlsPtr_.jpeer); 268dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers self->tlsPtr_.jpeer = nullptr; 269eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier self->SetThreadName(self->GetThreadName(soa)->ToModifiedUtf8().c_str()); 270a0b34518cf3f3801407624d95846f8ff90c05d25Narayan Kamath 271c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* priorityField = soa.DecodeField(WellKnownClasses::java_lang_Thread_priority); 272a0b34518cf3f3801407624d95846f8ff90c05d25Narayan Kamath self->SetNativePriority(priorityField->GetInt(self->tlsPtr_.opeer)); 273365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Dbg::PostThreadStart(self); 27493e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 275365c10235438607541fa2259a5fec48061b90bd8Ian Rogers // Invoke the 'run' method of our java.lang.Thread. 276dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers mirror::Object* receiver = self->tlsPtr_.opeer; 277365c10235438607541fa2259a5fec48061b90bd8Ian Rogers jmethodID mid = WellKnownClasses::java_lang_Thread_run; 27815e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao ScopedLocalRef<jobject> ref(soa.Env(), soa.AddLocalReference<jobject>(receiver)); 27915e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao InvokeVirtualOrInterfaceWithJValues(soa, ref.get(), mid, nullptr); 280365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Detach and delete self. 28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Runtime::Current()->GetThreadList()->Unregister(self); 28393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 2840aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 285b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 286b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 2872b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierThread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa, 2882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* thread_peer) { 289c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_nativePeer); 290ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Thread* result = reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetLong(thread_peer))); 29100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Sanity check that if we have a result it is either suspended or we hold the thread_list_lock_ 29200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // to stop it from going away. 29381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers if (kIsDebugBuild) { 29481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers MutexLock mu(soa.Self(), *Locks::thread_suspend_count_lock_); 2950aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (result != nullptr && !result->IsSuspended()) { 29681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Locks::thread_list_lock_->AssertHeld(soa.Self()); 29781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 29800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return result; 300761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes} 301761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes 3022b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierThread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa, 3032b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier jobject java_thread) { 3042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return FromManagedThread(soa, soa.Decode<mirror::Object*>(java_thread)); 30501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes} 30601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 307ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughesstatic size_t FixStackSize(size_t stack_size) { 3087502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // A stack size of zero means "use the default". 309d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes if (stack_size == 0) { 310d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes stack_size = Runtime::Current()->GetDefaultStackSize(); 311d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 31261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 3136414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom // Dalvik used the bionic pthread default stack size for native threads, 3146414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom // so include that here to support apps that expect large native stacks. 3156414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom stack_size += 1 * MB; 3166414a97a3c6dc101ae8ebc9480114d0c327e8e8dBrian Carlstrom 3177502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // It's not possible to request a stack smaller than the system-defined PTHREAD_STACK_MIN. 3187502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes if (stack_size < PTHREAD_STACK_MIN) { 3197502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes stack_size = PTHREAD_STACK_MIN; 3207502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes } 3217502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 322f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison if (Runtime::Current()->ExplicitStackOverflowChecks()) { 323f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // It's likely that callers are trying to ensure they have at least a certain amount of 324f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // stack space, so we should add our reserved space on top of what they requested, rather 325f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // than implicitly take it away from them. 3267ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe stack_size += GetStackOverflowReservedBytes(kRuntimeISA); 327f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison } else { 328f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // If we are going to use implicit stack checks, allocate space for the protected 329f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // region at the bottom of the stack. 330b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison stack_size += Thread::kStackOverflowImplicitCheckSize + 331b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison GetStackOverflowReservedBytes(kRuntimeISA); 332f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison } 3337502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 3347502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes // Some systems require the stack size to be a multiple of the system page size, so round up. 3357502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes stack_size = RoundUp(stack_size, kPageSize); 3367502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 3377502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes return stack_size; 3387502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes} 3397502e2a419f84808518cf212b3d7145c7b959c76Elliott Hughes 34069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// Global variable to prevent the compiler optimizing away the page reads for the stack. 34113735955f39b3b304c37d2b2840663c131262c18Ian Rogersuint8_t dont_optimize_this; 34269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 343f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison// Install a protected region in the stack. This is used to trigger a SIGSEGV if a stack 344648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison// overflow is detected. It is located right below the stack_begin_. 34569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// 346648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison// There is a little complexity here that deserves a special mention. On some 347648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison// architectures, the stack created using a VM_GROWSDOWN flag 34869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// to prevent memory being allocated when it's not needed. This flag makes the 34969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// kernel only allocate memory for the stack by growing down in memory. Because we 35069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// want to put an mprotected region far away from that at the stack top, we need 35169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// to make sure the pages for the stack are mapped in before we call mprotect. We do 35269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// this by reading every page from the stack bottom (highest address) to the stack top. 35369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison// We then madvise this away. 354648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allisonvoid Thread::InstallImplicitProtection() { 35513735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* pregion = tlsPtr_.stack_begin - kStackOverflowProtectedSize; 35613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* stack_himem = tlsPtr_.stack_end; 35713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* stack_top = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(&stack_himem) & 35869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison ~(kPageSize - 1)); // Page containing current top of stack. 35969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 360648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // First remove the protection on the protected region as will want to read and 361648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // write it. This may fail (on the first attempt when the stack is not mapped) 362648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // but we ignore that. 363648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison UnprotectStack(); 364f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 365648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // Map in the stack. This must be done by reading from the 366648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // current stack pointer downwards as the stack may be mapped using VM_GROWSDOWN 367648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // in the kernel. Any access more than a page below the current SP might cause 368648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // a segv. 369f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 370648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // Read every page from the high address to the low. 37113735955f39b3b304c37d2b2840663c131262c18Ian Rogers for (uint8_t* p = stack_top; p >= pregion; p -= kPageSize) { 372648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison dont_optimize_this = *p; 373f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison } 3745cd33753b96d92c03e3cb10cb802e68fb6ef2f21Dave Allison 375f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison VLOG(threads) << "installing stack protected region at " << std::hex << 376f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison static_cast<void*>(pregion) << " to " << 377f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison static_cast<void*>(pregion + kStackOverflowProtectedSize - 1); 378f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 379648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // Protect the bottom of the stack to prevent read/write to it. 380648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ProtectStack(); 3815cd33753b96d92c03e3cb10cb802e68fb6ef2f21Dave Allison 3825cd33753b96d92c03e3cb10cb802e68fb6ef2f21Dave Allison // Tell the kernel that we won't be needing these pages any more. 38369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // NB. madvise will probably write zeroes into the memory (on linux it does). 384648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison uint32_t unwanted_size = stack_top - pregion - kPageSize; 385648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison madvise(pregion, unwanted_size, MADV_DONTNEED); 386f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison} 387f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 388120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogersvoid Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) { 3890aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(java_peer != nullptr); 390120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Thread* self = static_cast<JNIEnvExt*>(env)->self; 391120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime* runtime = Runtime::Current(); 392dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier 393120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // Atomically start the birth of the thread ensuring the runtime isn't shutting down. 394120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers bool thread_start_during_shutdown = false; 395365c10235438607541fa2259a5fec48061b90bd8Ian Rogers { 396120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers MutexLock mu(self, *Locks::runtime_shutdown_lock_); 397590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (runtime->IsShuttingDownLocked()) { 398120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers thread_start_during_shutdown = true; 399120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } else { 400120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers runtime->StartThreadBirth(); 401120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 40200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 403120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers if (thread_start_during_shutdown) { 404120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers ScopedLocalRef<jclass> error_class(env, env->FindClass("java/lang/InternalError")); 405120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers env->ThrowNew(error_class.get(), "Thread starting during runtime shutdown"); 406120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return; 407120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 408120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 409120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Thread* child_thread = new Thread(is_daemon); 410120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // Use global JNI ref to hold peer live while child thread starts. 411dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers child_thread->tlsPtr_.jpeer = env->NewGlobalRef(java_peer); 412120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers stack_size = FixStackSize(stack_size); 413120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 4143c50a4b4ba6d7d9369ee9a0bd6d30bf4c9c79bb0Anwar Ghuloum // Thread.start is synchronized, so we know that nativePeer is 0, and know that we're not racing to 415120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // assign it. 416ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, 417ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers reinterpret_cast<jlong>(child_thread)); 41800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 419520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // Try to allocate a JNIEnvExt for the thread. We do this here as we might be out of memory and 420520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // do not have a good way to report this on the child's side. 421520abbd0edcf333f07164539620ce65258c72383Andreas Gampe std::unique_ptr<JNIEnvExt> child_jni_env_ext( 422520abbd0edcf333f07164539620ce65258c72383Andreas Gampe JNIEnvExt::Create(child_thread, Runtime::Current()->GetJavaVM())); 423520abbd0edcf333f07164539620ce65258c72383Andreas Gampe 424520abbd0edcf333f07164539620ce65258c72383Andreas Gampe int pthread_create_result = 0; 425520abbd0edcf333f07164539620ce65258c72383Andreas Gampe if (child_jni_env_ext.get() != nullptr) { 426520abbd0edcf333f07164539620ce65258c72383Andreas Gampe pthread_t new_pthread; 427520abbd0edcf333f07164539620ce65258c72383Andreas Gampe pthread_attr_t attr; 428520abbd0edcf333f07164539620ce65258c72383Andreas Gampe child_thread->tlsPtr_.tmp_jni_env = child_jni_env_ext.get(); 429520abbd0edcf333f07164539620ce65258c72383Andreas Gampe CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread"); 430520abbd0edcf333f07164539620ce65258c72383Andreas Gampe CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED), 431520abbd0edcf333f07164539620ce65258c72383Andreas Gampe "PTHREAD_CREATE_DETACHED"); 432520abbd0edcf333f07164539620ce65258c72383Andreas Gampe CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size); 433520abbd0edcf333f07164539620ce65258c72383Andreas Gampe pthread_create_result = pthread_create(&new_pthread, 434520abbd0edcf333f07164539620ce65258c72383Andreas Gampe &attr, 435520abbd0edcf333f07164539620ce65258c72383Andreas Gampe Thread::CreateCallback, 436520abbd0edcf333f07164539620ce65258c72383Andreas Gampe child_thread); 437520abbd0edcf333f07164539620ce65258c72383Andreas Gampe CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread"); 438520abbd0edcf333f07164539620ce65258c72383Andreas Gampe 439520abbd0edcf333f07164539620ce65258c72383Andreas Gampe if (pthread_create_result == 0) { 440520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // pthread_create started the new thread. The child is now responsible for managing the 441520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // JNIEnvExt we created. 442520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // Note: we can't check for tmp_jni_env == nullptr, as that would require synchronization 443520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // between the threads. 444520abbd0edcf333f07164539620ce65258c72383Andreas Gampe child_jni_env_ext.release(); 445520abbd0edcf333f07164539620ce65258c72383Andreas Gampe return; 4469efc3e03982f042c3ce67cc2c64dbe0f0986119bBrian Carlstrom } 447365c10235438607541fa2259a5fec48061b90bd8Ian Rogers } 448520abbd0edcf333f07164539620ce65258c72383Andreas Gampe 449520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // Either JNIEnvExt::Create or pthread_create(3) failed, so clean up. 450520abbd0edcf333f07164539620ce65258c72383Andreas Gampe { 451520abbd0edcf333f07164539620ce65258c72383Andreas Gampe MutexLock mu(self, *Locks::runtime_shutdown_lock_); 452520abbd0edcf333f07164539620ce65258c72383Andreas Gampe runtime->EndThreadBirth(); 453520abbd0edcf333f07164539620ce65258c72383Andreas Gampe } 454520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // Manually delete the global reference since Thread::Init will not have been run. 455520abbd0edcf333f07164539620ce65258c72383Andreas Gampe env->DeleteGlobalRef(child_thread->tlsPtr_.jpeer); 456520abbd0edcf333f07164539620ce65258c72383Andreas Gampe child_thread->tlsPtr_.jpeer = nullptr; 457520abbd0edcf333f07164539620ce65258c72383Andreas Gampe delete child_thread; 458520abbd0edcf333f07164539620ce65258c72383Andreas Gampe child_thread = nullptr; 459520abbd0edcf333f07164539620ce65258c72383Andreas Gampe // TODO: remove from thread group? 460520abbd0edcf333f07164539620ce65258c72383Andreas Gampe env->SetLongField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer, 0); 461520abbd0edcf333f07164539620ce65258c72383Andreas Gampe { 462520abbd0edcf333f07164539620ce65258c72383Andreas Gampe std::string msg(child_jni_env_ext.get() == nullptr ? 463520abbd0edcf333f07164539620ce65258c72383Andreas Gampe "Could not allocate JNI Env" : 464520abbd0edcf333f07164539620ce65258c72383Andreas Gampe StringPrintf("pthread_create (%s stack) failed: %s", 465520abbd0edcf333f07164539620ce65258c72383Andreas Gampe PrettySize(stack_size).c_str(), strerror(pthread_create_result))); 466520abbd0edcf333f07164539620ce65258c72383Andreas Gampe ScopedObjectAccess soa(env); 467520abbd0edcf333f07164539620ce65258c72383Andreas Gampe soa.Self()->ThrowOutOfMemoryError(msg.c_str()); 468520abbd0edcf333f07164539620ce65258c72383Andreas Gampe } 46993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes} 47061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 471520abbd0edcf333f07164539620ce65258c72383Andreas Gampebool Thread::Init(ThreadList* thread_list, JavaVMExt* java_vm, JNIEnvExt* jni_env_ext) { 472462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // This function does all the initialization that must be run by the native thread it applies to. 473462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // (When we create a new thread from managed code, we allocate the Thread* in Thread::Create so 474462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // we can handshake with the corresponding native thread when it's ready.) Check this native 475462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // thread hasn't been through here already... 4760aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(Thread::Current() == nullptr); 477f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers 478f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers // Set pthread_self_ ahead of pthread_setspecific, that makes Thread::Current function, this 479f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers // avoids pthread_self_ ever being invalid when discovered from Thread::Current(). 480f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers tlsPtr_.pthread_self = pthread_self(); 481f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers CHECK(is_started_); 482f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers 483d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes SetUpAlternateSignalStack(); 484f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers if (!InitStackHwm()) { 485f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers return false; 486f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers } 48793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes InitCpu(); 488848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers InitTlsEntryPoints(); 489b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison RemoveSuspendTrigger(); 4905d76c435082332ef79a22962386fa92a0870e378Ian Rogers InitCardTable(); 49101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers InitTid(); 492f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers 4936a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach self"); 494120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers DCHECK_EQ(Thread::Current(), this); 495a5780dad67556297c8ca5f2608c53b193e6c4514Elliott Hughes 496dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.thin_lock_thread_id = thread_list->AllocThreadId(this); 4975fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 498520abbd0edcf333f07164539620ce65258c72383Andreas Gampe if (jni_env_ext != nullptr) { 499520abbd0edcf333f07164539620ce65258c72383Andreas Gampe DCHECK_EQ(jni_env_ext->vm, java_vm); 500520abbd0edcf333f07164539620ce65258c72383Andreas Gampe DCHECK_EQ(jni_env_ext->self, this); 501520abbd0edcf333f07164539620ce65258c72383Andreas Gampe tlsPtr_.jni_env = jni_env_ext; 502520abbd0edcf333f07164539620ce65258c72383Andreas Gampe } else { 503520abbd0edcf333f07164539620ce65258c72383Andreas Gampe tlsPtr_.jni_env = JNIEnvExt::Create(this, java_vm); 504520abbd0edcf333f07164539620ce65258c72383Andreas Gampe if (tlsPtr_.jni_env == nullptr) { 505520abbd0edcf333f07164539620ce65258c72383Andreas Gampe return false; 506520abbd0edcf333f07164539620ce65258c72383Andreas Gampe } 5073f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe } 5083f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe 509120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers thread_list->Register(this); 510f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers return true; 51193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes} 51293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 513664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu ChartierThread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_group, 514664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier bool create_peer) { 515120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime* runtime = Runtime::Current(); 5160aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (runtime == nullptr) { 517120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOG(ERROR) << "Thread attaching to non-existent runtime: " << thread_name; 5180aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 519120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 520f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers Thread* self; 521120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers { 5220aded089f565008ba5908e395e5914ca4f91f2deDave Allison MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_); 523590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (runtime->IsShuttingDownLocked()) { 524120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOG(ERROR) << "Thread attaching while runtime is shutting down: " << thread_name; 5250aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 526120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } else { 527120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime::Current()->StartThreadBirth(); 528120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers self = new Thread(as_daemon); 529f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers bool init_success = self->Init(runtime->GetThreadList(), runtime->GetJavaVM()); 530120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Runtime::Current()->EndThreadBirth(); 531f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers if (!init_success) { 532f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers delete self; 533f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers return nullptr; 534f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers } 535120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 536120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 5375fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 538848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao self->InitStringEntryPoints(); 539848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 540dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier CHECK_NE(self->GetState(), kRunnable); 541dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier self->SetState(kNative); 542726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes 543cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // If we're the main thread, ClassLinker won't be created until after we're attached, 544cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // so that thread needs a two-stage attach. Regular threads don't need this hack. 545d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // In the compiler, all threads need this hack, because no-one's going to be getting 546d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes // a native peer! 547664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier if (create_peer) { 548462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes self->CreatePeer(thread_name, as_daemon, thread_group); 54906e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes } else { 55006e3ad4a651c2c58dba5e865cd06d2f98462bf1dElliott Hughes // These aren't necessary, but they improve diagnostics for unit tests & command-line tools. 5510aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread_name != nullptr) { 552dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers self->tlsPtr_.name->assign(thread_name); 55322869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes ::art::SetThreadName(thread_name); 5543ea69c0abce1b81b3c45033867d49b00e6d6b709Brian Carlstrom } else if (self->GetJniEnv()->check_jni) { 5553ea69c0abce1b81b3c45033867d49b00e6d6b709Brian Carlstrom LOG(WARNING) << *Thread::Current() << " attached without supplying a name"; 55622869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes } 55736e0a955e48e9357bff1eab783e493107ebfff62Ian Rogers } 558cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 559dfafeef139dbc77e86fdb465d960b4a17a7ac4a0Daniel Mihalyi { 560dfafeef139dbc77e86fdb465d960b4a17a7ac4a0Daniel Mihalyi ScopedObjectAccess soa(self); 561dfafeef139dbc77e86fdb465d960b4a17a7ac4a0Daniel Mihalyi Dbg::PostThreadStart(self); 562dfafeef139dbc77e86fdb465d960b4a17a7ac4a0Daniel Mihalyi } 563dfafeef139dbc77e86fdb465d960b4a17a7ac4a0Daniel Mihalyi 5645fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes return self; 5655fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes} 5665fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 567365c10235438607541fa2259a5fec48061b90bd8Ian Rogersvoid Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group) { 568365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Runtime* runtime = Runtime::Current(); 569365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(runtime->IsStarted()); 570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers JNIEnv* env = tlsPtr_.jni_env; 5715fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 5720aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread_group == nullptr) { 573365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group = runtime->GetMainThreadGroup(); 574462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes } 575726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes ScopedLocalRef<jobject> thread_name(env, env->NewStringUTF(name)); 576e07fd17f3c45034470eb6f5a265152a39854995cMathieu Chartier // Add missing null check in case of OOM b/18297817 577445120568460cae68d37a27ac39477fbf20952fcVladimir Marko if (name != nullptr && thread_name.get() == nullptr) { 578e07fd17f3c45034470eb6f5a265152a39854995cMathieu Chartier CHECK(IsExceptionPending()); 579e07fd17f3c45034470eb6f5a265152a39854995cMathieu Chartier return; 580e07fd17f3c45034470eb6f5a265152a39854995cMathieu Chartier } 5818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes jint thread_priority = GetNativePriority(); 5825fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes jboolean thread_is_daemon = as_daemon; 5835fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 584eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes ScopedLocalRef<jobject> peer(env, env->AllocObject(WellKnownClasses::java_lang_Thread)); 5850aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (peer.get() == nullptr) { 586dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier CHECK(IsExceptionPending()); 587dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier return; 5885d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 589cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers { 590cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedObjectAccess soa(this); 591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.opeer = soa.Decode<mirror::Object*>(peer.get()); 592cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers } 593eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes env->CallNonvirtualVoidMethod(peer.get(), 594eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes WellKnownClasses::java_lang_Thread, 595eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes WellKnownClasses::java_lang_Thread_init, 596365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group, thread_name.get(), thread_priority, thread_is_daemon); 59700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers AssertNoPendingException(); 598d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 599120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Thread* self = this; 600120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers DCHECK_EQ(self, Thread::Current()); 601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers env->SetLongField(peer.get(), WellKnownClasses::java_lang_Thread_nativePeer, 602dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers reinterpret_cast<jlong>(self)); 603120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 604120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers ScopedObjectAccess soa(self); 605eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 6065a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe MutableHandle<mirror::String> peer_thread_name(hs.NewHandle(GetThreadName(soa))); 607eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (peer_thread_name.Get() == nullptr) { 60800fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // The Thread constructor should have set the Thread.name to a 60900fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // non-null value. However, because we can run without code 61000fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // available (in the compiler, in tests), we manually assign the 61100fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom // fields the constructor should have set. 612d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (runtime->IsActiveTransaction()) { 613d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InitPeer<true>(soa, thread_is_daemon, thread_group, thread_name.get(), thread_priority); 614d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 615d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InitPeer<false>(soa, thread_is_daemon, thread_group, thread_name.get(), thread_priority); 616d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 617eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier peer_thread_name.Assign(GetThreadName(soa)); 61800fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 619225f5a1df25241babd16cdba54056b9e2cd166a2Elliott Hughes // 'thread_name' may have been null, so don't trust 'peer_thread_name' to be non-null. 620eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (peer_thread_name.Get() != nullptr) { 621899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes SetThreadName(peer_thread_name->ToModifiedUtf8().c_str()); 62200fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 62361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 62461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 625d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertztemplate<bool kTransactionActive> 626d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Thread::InitPeer(ScopedObjectAccess& soa, jboolean thread_is_daemon, jobject thread_group, 627d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz jobject thread_name, jint thread_priority) { 628d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)-> 629dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetBoolean<kTransactionActive>(tlsPtr_.opeer, thread_is_daemon); 630d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz soa.DecodeField(WellKnownClasses::java_lang_Thread_group)-> 631dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object*>(thread_group)); 632d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz soa.DecodeField(WellKnownClasses::java_lang_Thread_name)-> 633dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object*>(thread_name)); 634d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz soa.DecodeField(WellKnownClasses::java_lang_Thread_priority)-> 635dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetInt<kTransactionActive>(tlsPtr_.opeer, thread_priority); 636d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 637d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 638899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughesvoid Thread::SetThreadName(const char* name) { 639dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.name->assign(name); 640899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes ::art::SetThreadName(name); 641899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes Dbg::DdmSendThreadNotification(this, CHUNK_TYPE("THNM")); 642899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes} 643899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes 644f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogersbool Thread::InitStackHwm() { 645dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void* read_stack_base; 646dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers size_t read_stack_size; 6476d3fc5615612e500a00aba0a0d331436fae8d996Elliott Hughes size_t read_guard_size; 6486d3fc5615612e500a00aba0a0d331436fae8d996Elliott Hughes GetThreadStack(tlsPtr_.pthread_self, &read_stack_base, &read_stack_size, &read_guard_size); 64936ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 65013735955f39b3b304c37d2b2840663c131262c18Ian Rogers tlsPtr_.stack_begin = reinterpret_cast<uint8_t*>(read_stack_base); 651dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.stack_size = read_stack_size; 65236ecb789775eb5bd284ce5dd35d2e31e42354f24Elliott Hughes 653648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // The minimum stack size we can cope with is the overflow reserved bytes (typically 654648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // 8K) + the protected region size (4K) + another page (4K). Typically this will 655648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // be 8+4+4 = 16K. The thread won't be able to do much with this stack even the GC takes 656648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // between 8K and 12K. 657648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison uint32_t min_stack = GetStackOverflowReservedBytes(kRuntimeISA) + kStackOverflowProtectedSize 658648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison + 4 * KB; 659648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (read_stack_size <= min_stack) { 660f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers // Note, as we know the stack is small, avoid operations that could use a lot of stack. 661f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers LogMessage::LogLineLowStack(__PRETTY_FUNCTION__, __LINE__, ERROR, 662f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers "Attempt to attach a thread with a too-small stack"); 663f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers return false; 664be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes } 665449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes 666b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko // This is included in the SIGQUIT output, but it's useful here for thread debugging. 667b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko VLOG(threads) << StringPrintf("Native stack is at %p (%s with %s guard)", 668b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko read_stack_base, 669b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko PrettySize(read_stack_size).c_str(), 670b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko PrettySize(read_guard_size).c_str()); 671b8f2f63c3d5f0d6fb2a165b3fb8379608076ddaeVladimir Marko 672932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Set stack_end_ to the bottom of the stack saving space of stack overflows 6738e219ae27624116b6d23e858fb21e93342f81d66Mathieu Chartier 6748e219ae27624116b6d23e858fb21e93342f81d66Mathieu Chartier Runtime* runtime = Runtime::Current(); 675e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier bool implicit_stack_check = !runtime->ExplicitStackOverflowChecks() && !runtime->IsAotCompiler(); 676b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison ResetDefaultStackEnd(); 677f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 678f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison // Install the protected region if we are doing implicit overflow checks. 679f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison if (implicit_stack_check) { 680648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // The thread might have protected region at the bottom. We need 681648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // to install our own region so we need to move the limits 682648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // of the stack to make room for it. 683216cf23663789b06508f65f6dc0a72f181c9c03aDave Allison 6846d3fc5615612e500a00aba0a0d331436fae8d996Elliott Hughes tlsPtr_.stack_begin += read_guard_size + kStackOverflowProtectedSize; 6856d3fc5615612e500a00aba0a0d331436fae8d996Elliott Hughes tlsPtr_.stack_end += read_guard_size + kStackOverflowProtectedSize; 6866d3fc5615612e500a00aba0a0d331436fae8d996Elliott Hughes tlsPtr_.stack_size -= read_guard_size; 687648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 688648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison InstallImplicitProtection(); 689f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison } 690449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes 691449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes // Sanity check. 692449b4bdf90b527ef7a42faaf087494538e62363cElliott Hughes int stack_variable; 693dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK_GT(&stack_variable, reinterpret_cast<void*>(tlsPtr_.stack_end)); 694f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers 695f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers return true; 696be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes} 697be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 69800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Thread::ShortDump(std::ostream& os) const { 69900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers os << "Thread["; 700d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers if (GetThreadId() != 0) { 70100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // If we're in kStarting, we won't have a thin lock id or tid yet. 702d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers os << GetThreadId() 703b28412e3fcc97fbcd0a11d25703a4ad64c3d9552Mathieu Chartier << ",tid=" << GetTid() << ','; 704e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes } 705474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers os << GetState() 706b28412e3fcc97fbcd0a11d25703a4ad64c3d9552Mathieu Chartier << ",Thread*=" << this 707b28412e3fcc97fbcd0a11d25703a4ad64c3d9552Mathieu Chartier << ",peer=" << tlsPtr_.opeer 708b28412e3fcc97fbcd0a11d25703a4ad64c3d9552Mathieu Chartier << ",\"" << (tlsPtr_.name != nullptr ? *tlsPtr_.name : "null") << "\"" 709b28412e3fcc97fbcd0a11d25703a4ad64c3d9552Mathieu Chartier << "]"; 710d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes} 711d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 71200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Thread::Dump(std::ostream& os) const { 71300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DumpState(os); 71400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DumpStack(os); 71500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 71600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 7172b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartiermirror::String* Thread::GetThreadName(const ScopedObjectAccessAlreadyRunnable& soa) const { 718c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name); 7192cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return (tlsPtr_.opeer != nullptr) ? 7202cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<mirror::String*>(f->GetObject(tlsPtr_.opeer)) : nullptr; 721fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes} 722fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 723ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughesvoid Thread::GetThreadName(std::string& name) const { 724dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers name.assign(*tlsPtr_.name); 725ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes} 726ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes 72757dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Haouint64_t Thread::GetCpuMicroTime() const { 7280a18df82f4dea95b7398f8c934341fccbf04eeeeElliott Hughes#if defined(__linux__) 72957dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao clockid_t cpu_clock_id; 730dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers pthread_getcpuclockid(tlsPtr_.pthread_self, &cpu_clock_id); 73157dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao timespec now; 73257dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao clock_gettime(cpu_clock_id, &now); 7330f6784737882199197796b67b99e5f1ded383beeIan Rogers return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000); 7340a18df82f4dea95b7398f8c934341fccbf04eeeeElliott Hughes#else // __APPLE__ 73557dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao UNIMPLEMENTED(WARNING); 73657dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao return -1; 73757dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao#endif 73857dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao} 73957dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao 74001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers// Attempt to rectify locks so that we dump thread list with required locks before exiting. 74101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersstatic void UnsafeLogFatalForSuspendCount(Thread* self, Thread* thread) NO_THREAD_SAFETY_ANALYSIS { 742120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOG(ERROR) << *thread << " suspend count already zero."; 74301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers Locks::thread_suspend_count_lock_->Unlock(self); 74401ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers if (!Locks::mutator_lock_->IsSharedHeld(self)) { 74501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers Locks::mutator_lock_->SharedTryLock(self); 74601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers if (!Locks::mutator_lock_->IsSharedHeld(self)) { 74701ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers LOG(WARNING) << "Dumping thread list without holding mutator_lock_"; 74801ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers } 74901ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers } 75001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers if (!Locks::thread_list_lock_->IsExclusiveHeld(self)) { 75101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers Locks::thread_list_lock_->TryLock(self); 75201ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers if (!Locks::thread_list_lock_->IsExclusiveHeld(self)) { 75301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers LOG(WARNING) << "Dumping thread list without holding thread_list_lock_"; 75401ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers } 75501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers } 75601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers std::ostringstream ss; 7577b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers Runtime::Current()->GetThreadList()->Dump(ss); 758120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOG(FATAL) << ss.str(); 75901ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers} 76001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers 76101ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogersvoid Thread::ModifySuspendCount(Thread* self, int delta, bool for_debugger) { 7622966e13d504a72d55c62bf864e183ec80703c699Ian Rogers if (kIsDebugBuild) { 7632966e13d504a72d55c62bf864e183ec80703c699Ian Rogers DCHECK(delta == -1 || delta == +1 || delta == -tls32_.debug_suspend_count) 7642966e13d504a72d55c62bf864e183ec80703c699Ian Rogers << delta << " " << tls32_.debug_suspend_count << " " << this; 7652966e13d504a72d55c62bf864e183ec80703c699Ian Rogers DCHECK_GE(tls32_.suspend_count, tls32_.debug_suspend_count) << this; 7662966e13d504a72d55c62bf864e183ec80703c699Ian Rogers Locks::thread_suspend_count_lock_->AssertHeld(self); 7672966e13d504a72d55c62bf864e183ec80703c699Ian Rogers if (this != self && !IsSuspended()) { 7682966e13d504a72d55c62bf864e183ec80703c699Ian Rogers Locks::thread_list_lock_->AssertHeld(self); 7692966e13d504a72d55c62bf864e183ec80703c699Ian Rogers } 770cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers } 771dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (UNLIKELY(delta < 0 && tls32_.suspend_count <= 0)) { 77201ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers UnsafeLogFatalForSuspendCount(self, this); 77300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return; 77400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 77501ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers 776dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.suspend_count += delta; 77700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (for_debugger) { 778dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.debug_suspend_count += delta; 77900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 78001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers 781dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tls32_.suspend_count == 0) { 782474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers AtomicClearFlag(kSuspendRequest); 783474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers } else { 784474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers AtomicSetFlag(kSuspendRequest); 785b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison TriggerSuspend(); 786474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers } 78700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 78800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 789752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartiervoid Thread::RunCheckpointFunction() { 7900aded089f565008ba5908e395e5914ca4f91f2deDave Allison Closure *checkpoints[kMaxCheckpoints]; 7910aded089f565008ba5908e395e5914ca4f91f2deDave Allison 7920aded089f565008ba5908e395e5914ca4f91f2deDave Allison // Grab the suspend_count lock and copy the current set of 7930aded089f565008ba5908e395e5914ca4f91f2deDave Allison // checkpoints. Then clear the list and the flag. The RequestCheckpoint 7940aded089f565008ba5908e395e5914ca4f91f2deDave Allison // function will also grab this lock so we prevent a race between setting 7950aded089f565008ba5908e395e5914ca4f91f2deDave Allison // the kCheckpointRequest flag and clearing it. 7960aded089f565008ba5908e395e5914ca4f91f2deDave Allison { 7970aded089f565008ba5908e395e5914ca4f91f2deDave Allison MutexLock mu(this, *Locks::thread_suspend_count_lock_); 7980aded089f565008ba5908e395e5914ca4f91f2deDave Allison for (uint32_t i = 0; i < kMaxCheckpoints; ++i) { 799dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers checkpoints[i] = tlsPtr_.checkpoint_functions[i]; 800dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.checkpoint_functions[i] = nullptr; 8010aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8020aded089f565008ba5908e395e5914ca4f91f2deDave Allison AtomicClearFlag(kCheckpointRequest); 8030aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8040aded089f565008ba5908e395e5914ca4f91f2deDave Allison 8050aded089f565008ba5908e395e5914ca4f91f2deDave Allison // Outside the lock, run all the checkpoint functions that 8060aded089f565008ba5908e395e5914ca4f91f2deDave Allison // we collected. 8070aded089f565008ba5908e395e5914ca4f91f2deDave Allison bool found_checkpoint = false; 8080aded089f565008ba5908e395e5914ca4f91f2deDave Allison for (uint32_t i = 0; i < kMaxCheckpoints; ++i) { 8090aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (checkpoints[i] != nullptr) { 8100aded089f565008ba5908e395e5914ca4f91f2deDave Allison ATRACE_BEGIN("Checkpoint function"); 8110aded089f565008ba5908e395e5914ca4f91f2deDave Allison checkpoints[i]->Run(this); 8120aded089f565008ba5908e395e5914ca4f91f2deDave Allison ATRACE_END(); 8130aded089f565008ba5908e395e5914ca4f91f2deDave Allison found_checkpoint = true; 8140aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8150aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8160aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(found_checkpoint); 817752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier} 818752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier 8190e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartierbool Thread::RequestCheckpoint(Closure* function) { 82059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman union StateAndFlags old_state_and_flags; 821dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers old_state_and_flags.as_int = tls32_.state_and_flags.as_int; 822d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers if (old_state_and_flags.as_struct.state != kRunnable) { 823d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return false; // Fail, thread is suspended and so can't run a checkpoint. 824d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 8250aded089f565008ba5908e395e5914ca4f91f2deDave Allison 8260aded089f565008ba5908e395e5914ca4f91f2deDave Allison uint32_t available_checkpoint = kMaxCheckpoints; 8270aded089f565008ba5908e395e5914ca4f91f2deDave Allison for (uint32_t i = 0 ; i < kMaxCheckpoints; ++i) { 828dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tlsPtr_.checkpoint_functions[i] == nullptr) { 8290aded089f565008ba5908e395e5914ca4f91f2deDave Allison available_checkpoint = i; 8300aded089f565008ba5908e395e5914ca4f91f2deDave Allison break; 8310aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8320aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 8330aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (available_checkpoint == kMaxCheckpoints) { 8340aded089f565008ba5908e395e5914ca4f91f2deDave Allison // No checkpoint functions available, we can't run a checkpoint 8350aded089f565008ba5908e395e5914ca4f91f2deDave Allison return false; 836d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 837dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.checkpoint_functions[available_checkpoint] = function; 8380aded089f565008ba5908e395e5914ca4f91f2deDave Allison 839d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Checkpoint function installed now install flag bit. 840858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier // We must be runnable to request a checkpoint. 8415f51d4b80058236759fea1d932470a57f348c199Mathieu Chartier DCHECK_EQ(old_state_and_flags.as_struct.state, kRunnable); 84259cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman union StateAndFlags new_state_and_flags; 84359cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman new_state_and_flags.as_int = old_state_and_flags.as_int; 844858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier new_state_and_flags.as_struct.flags |= kCheckpointRequest; 8453d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier bool success = tls32_.state_and_flags.as_atomic_int.CompareExchangeStrongSequentiallyConsistent( 8462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier old_state_and_flags.as_int, new_state_and_flags.as_int); 8478c1b5f71a8005743756206120624121d7678381fIan Rogers if (UNLIKELY(!success)) { 848d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // The thread changed state before the checkpoint was installed. 849dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK_EQ(tlsPtr_.checkpoint_functions[available_checkpoint], function); 850dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.checkpoint_functions[available_checkpoint] = nullptr; 8510aded089f565008ba5908e395e5914ca4f91f2deDave Allison } else { 8520aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK_EQ(ReadFlag(kCheckpointRequest), true); 853b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison TriggerSuspend(); 854d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers } 8558c1b5f71a8005743756206120624121d7678381fIan Rogers return success; 856858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier} 857858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier 8582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi YamauchiClosure* Thread::GetFlipFunction() { 8592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Atomic<Closure*>* atomic_func = reinterpret_cast<Atomic<Closure*>*>(&tlsPtr_.flip_function); 8602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Closure* func; 8612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi do { 8622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi func = atomic_func->LoadRelaxed(); 8632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (func == nullptr) { 8642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 8652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 8662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } while (!atomic_func->CompareExchangeWeakSequentiallyConsistent(func, nullptr)); 8672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(func != nullptr); 8682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return func; 8692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 8702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 8712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchivoid Thread::SetFlipFunction(Closure* function) { 8722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi CHECK(function != nullptr); 8732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Atomic<Closure*>* atomic_func = reinterpret_cast<Atomic<Closure*>*>(&tlsPtr_.flip_function); 8742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi atomic_func->StoreSequentiallyConsistent(function); 8752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 87700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Thread::FullSuspendCheck() { 87800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(threads) << this << " self-suspending"; 879752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier ATRACE_BEGIN("Full suspend check"); 88000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Make thread appear suspended to other threads, release mutator_lock_. 8812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi tls32_.suspended_at_suspend_check = true; 88200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers TransitionFromRunnableToSuspended(kSuspended); 88300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Transition back to runnable noting requests to suspend, re-acquire share on mutator_lock_. 88400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers TransitionFromSuspendedToRunnable(); 8852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi tls32_.suspended_at_suspend_check = false; 886752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu Chartier ATRACE_END(); 88700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(threads) << this << " self-reviving"; 88800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 88900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 890abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughesvoid Thread::DumpState(std::ostream& os, const Thread* thread, pid_t tid) { 891d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes std::string group_name; 892d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes int priority; 893d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes bool is_daemon = false; 89481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Thread* self = Thread::Current(); 895d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 8962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // If flip_function is not null, it means we have run a checkpoint 8972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // before the thread wakes up to execute the flip function and the 8982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // thread roots haven't been forwarded. So the following access to 8992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // the roots (opeer or methods in the frames) would be bad. Run it 9002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // here. TODO: clean up. 9012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (thread != nullptr) { 9022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ScopedObjectAccessUnchecked soa(self); 9032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* this_thread = const_cast<Thread*>(thread); 9042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Closure* flip_func = this_thread->GetFlipFunction(); 9052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (flip_func != nullptr) { 9062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi flip_func->Run(this_thread); 9072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 9082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 9092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 910c7a966dbba6902618ff0959d604c05d7570df8c8Mathieu Chartier // Don't do this if we are aborting since the GC may have all the threads suspended. This will 911c7a966dbba6902618ff0959d604c05d7570df8c8Mathieu Chartier // cause ScopedObjectAccessUnchecked to deadlock. 912db978719dbcb73fc6acfd193561445c4462786b8Nicolas Geoffray if (gAborting == 0 && self != nullptr && thread != nullptr && thread->tlsPtr_.opeer != nullptr) { 913cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedObjectAccessUnchecked soa(self); 914dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers priority = soa.DecodeField(WellKnownClasses::java_lang_Thread_priority) 915dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ->GetInt(thread->tlsPtr_.opeer); 916dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers is_daemon = soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon) 917dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ->GetBoolean(thread->tlsPtr_.opeer); 918d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 9192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* thread_group = 920dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(thread->tlsPtr_.opeer); 921120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 9220aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread_group != nullptr) { 923c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* group_name_field = 9242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name); 9252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::String* group_name_string = 9262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers reinterpret_cast<mirror::String*>(group_name_field->GetObject(thread_group)); 9270aded089f565008ba5908e395e5914ca4f91f2deDave Allison group_name = (group_name_string != nullptr) ? group_name_string->ToModifiedUtf8() : "<null>"; 928d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 929d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } else { 930d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes priority = GetNativePriority(); 931dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes } 932d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 933abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes std::string scheduler_group_name(GetSchedulerGroupName(tid)); 9341bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes if (scheduler_group_name.empty()) { 9351bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes scheduler_group_name = "default"; 936d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 937d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 9380aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread != nullptr) { 939dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << '"' << *thread->tlsPtr_.name << '"'; 940abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (is_daemon) { 941abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " daemon"; 942abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 943abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " prio=" << priority 944d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers << " tid=" << thread->GetThreadId() 94580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes << " " << thread->GetState(); 94680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes if (thread->IsStillStarting()) { 94780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes os << " (still starting up)"; 94880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes } 94980537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes os << "\n"; 950abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } else { 951289be85116aaf7c48413858b5d0448868b4e61f3Elliott Hughes os << '"' << ::art::GetThreadName(tid) << '"' 952abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " prio=" << priority 953abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " (not attached)\n"; 954abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 955abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 9560aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread != nullptr) { 95781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers MutexLock mu(self, *Locks::thread_suspend_count_lock_); 958abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " | group=\"" << group_name << "\"" 959dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << " sCount=" << thread->tls32_.suspend_count 960dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << " dsCount=" << thread->tls32_.debug_suspend_count 961dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << " obj=" << reinterpret_cast<void*>(thread->tlsPtr_.opeer) 962abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " self=" << reinterpret_cast<const void*>(thread) << "\n"; 963d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 9640d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes 965abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes os << " | sysTid=" << tid 966abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " nice=" << getpriority(PRIO_PROCESS, tid) 9670d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes << " cgrp=" << scheduler_group_name; 9680aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread != nullptr) { 9690d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes int policy; 9700d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes sched_param sp; 971dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK_PTHREAD_CALL(pthread_getschedparam, (thread->tlsPtr_.pthread_self, &policy, &sp), 972dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers __FUNCTION__); 9730d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes os << " sched=" << policy << "/" << sp.sched_priority 974dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << " handle=" << reinterpret_cast<void*>(thread->tlsPtr_.pthread_self); 9750d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes } 9760d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes os << "\n"; 977d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 978d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes // Grab the scheduler stats for this thread. 979d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes std::string scheduler_stats; 980abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes if (ReadFileToString(StringPrintf("/proc/self/task/%d/schedstat", tid), &scheduler_stats)) { 9817934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom scheduler_stats.resize(scheduler_stats.size() - 1); // Lose the trailing '\n'. 982d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } else { 983d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes scheduler_stats = "0 0 0"; 984d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes } 985d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 986ba0b9c55adce3f533845ab1b25c552589e5b4118Elliott Hughes char native_thread_state = '?'; 987d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int utime = 0; 988d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int stime = 0; 989d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes int task_cpu = 0; 9902921201dce37ba40c55b89c0deca3c34bf64168eBrian Carlstrom GetTaskStats(tid, &native_thread_state, &utime, &stime, &task_cpu); 991d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 992ba0b9c55adce3f533845ab1b25c552589e5b4118Elliott Hughes os << " | state=" << native_thread_state 993ba0b9c55adce3f533845ab1b25c552589e5b4118Elliott Hughes << " schedstat=( " << scheduler_stats << " )" 994d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes << " utm=" << utime 995d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes << " stm=" << stime 996abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " core=" << task_cpu 997abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes << " HZ=" << sysconf(_SC_CLK_TCK) << "\n"; 9980aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (thread != nullptr) { 999dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << " | stack=" << reinterpret_cast<void*>(thread->tlsPtr_.stack_begin) << "-" 1000dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << reinterpret_cast<void*>(thread->tlsPtr_.stack_end) << " stackSize=" 1001dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers << PrettySize(thread->tlsPtr_.stack_size) << "\n"; 10029db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier // Dump the held mutexes. 10039db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier os << " | held mutexes="; 10049db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier for (size_t i = 0; i < kLockLevelCount; ++i) { 10059db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier if (i != kMonitorLock) { 10069db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier BaseMutex* mutex = thread->GetHeldMutex(static_cast<LockLevel>(i)); 10079db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier if (mutex != nullptr) { 10089db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier os << " \"" << mutex->GetName() << "\""; 10099db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier if (mutex->IsReaderWriterMutex()) { 10109db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier ReaderWriterMutex* rw_mutex = down_cast<ReaderWriterMutex*>(mutex); 1011a9d8c4ce62fff49580fa70d3fcb3aee45344d8caIan Rogers if (rw_mutex->GetExclusiveOwnerTid() == static_cast<uint64_t>(tid)) { 10129db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier os << "(exclusive held)"; 10139db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } else { 10149db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier os << "(shared held)"; 10159db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } 10169db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } 10179db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } 10189db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } 10199db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier } 10209db911eb76976fc1c73c8e563beb3620f1cadf99Mathieu Chartier os << "\n"; 1021abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes } 1022abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes} 1023abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 1024abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughesvoid Thread::DumpState(std::ostream& os) const { 1025abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes Thread::DumpState(os, this, GetTid()); 1026a09576416788b916095739e43a16917e7948f3a4Elliott Hughes} 1027a09576416788b916095739e43a16917e7948f3a4Elliott Hughes 10280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersstruct StackDumpVisitor : public StackVisitor { 1029277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe StackDumpVisitor(std::ostream& os_in, Thread* thread_in, Context* context, bool can_allocate_in) 1030b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 10318e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread_in, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames), 10328e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray os(os_in), 10338e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray thread(thread_in), 10348e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray can_allocate(can_allocate_in), 10358e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray last_method(nullptr), 10368e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray last_line_number(0), 10378e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray repetition_count(0), 10388e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray frame_count(0) {} 1039d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 1040bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers virtual ~StackDumpVisitor() { 1041e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes if (frame_count == 0) { 1042e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes os << " (no managed stack frames)\n"; 1043e85d2e924953f1a13b7152edba1c13853e6f3a86Elliott Hughes } 1044d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 1045d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 1046b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 10473d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* m = GetMethod(); 10480399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (m->IsRuntimeMethod()) { 1049530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 10509086572fa809d1a19d886b467e4da3ce42016982Ian Rogers } 10513387f39750942b0442eec351757c7d1f9b1405caMathieu Chartier m = m->GetInterfaceMethodIfProxy(sizeof(void*)); 105228ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers const int kMaxRepetition = 3; 10532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = m->GetDeclaringClass(); 1054ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::DexCache* dex_cache = c->GetDexCache(); 1055b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers int line_number = -1; 10560aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (dex_cache != nullptr) { // be tolerant of bad input 10574445a7e3398a6143939168097a3aa275b734504dIan Rogers const DexFile& dex_file = *dex_cache->GetDexFile(); 1058c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier line_number = dex_file.GetLineNumFromPC(m, GetDexPc(false)); 1059b861dc0077342d5a1d2dd9cade3f6990620778ecIan Rogers } 106028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (line_number == last_line_number && last_method == m) { 10610aded089f565008ba5908e395e5914ca4f91f2deDave Allison ++repetition_count; 1062d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } else { 106328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (repetition_count >= kMaxRepetition) { 106428ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << " ... repeated " << (repetition_count - kMaxRepetition) << " times\n"; 106528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 106628ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers repetition_count = 0; 106728ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers last_line_number = line_number; 106828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers last_method = m; 106928ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 107028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (repetition_count < kMaxRepetition) { 107128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << " at " << PrettyMethod(m, false); 107228ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers if (m->IsNative()) { 107328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << "(Native method)"; 107428ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } else { 1075bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* source_file(m->GetDeclaringClassSourceFile()); 10760aded089f565008ba5908e395e5914ca4f91f2deDave Allison os << "(" << (source_file != nullptr ? source_file : "unavailable") 10772e450bf45e1bacc9c356f6ab239ccfb31bd8d7e4Brian Carlstrom << ":" << line_number << ")"; 107828ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers } 107928ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers os << "\n"; 108008fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes if (frame_count == 0) { 108108fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes Monitor::DescribeWait(os, thread); 108208fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes } 108308fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes if (can_allocate) { 1084956a5228276693a7317ae6b41bfe7a7f0f3cbe6bAndreas Gampe // Visit locks, but do not abort on errors. This would trigger a nested abort. 1085956a5228276693a7317ae6b41bfe7a7f0f3cbe6bAndreas Gampe Monitor::VisitLocks(this, DumpLockedObject, &os, false); 108608fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes } 1087d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 10888e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 108908fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes ++frame_count; 1090530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 1091d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes } 10924993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 10932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static void DumpLockedObject(mirror::Object* o, void* context) 10944993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 10954993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes std::ostream& os = *reinterpret_cast<std::ostream*>(context); 1096d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers os << " - locked "; 1097d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers if (o == nullptr) { 1098d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers os << "an unknown object"; 1099d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers } else { 11004d7f61d44a732cfbc8573e5d93364983fd746888Mathieu Chartier if ((o->GetLockWord(false).GetState() == LockWord::kThinLocked) && 1101d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers Locks::mutator_lock_->IsExclusiveHeld(Thread::Current())) { 1102d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers // Getting the identity hashcode here would result in lock inflation and suspension of the 1103d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers // current thread, which isn't safe if this is the only runnable thread. 1104d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers os << StringPrintf("<@addr=0x%" PRIxPTR "> (a %s)", reinterpret_cast<intptr_t>(o), 1105d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers PrettyTypeOf(o).c_str()); 1106d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers } else { 1107e6a8eec3a5db28de7d5db6d78e38033b80740e49Mathieu Chartier // IdentityHashCode can cause thread suspension, which would invalidate o if it moved. So 1108e6a8eec3a5db28de7d5db6d78e38033b80740e49Mathieu Chartier // we get the pretty type beofre we call IdentityHashCode. 1109e6a8eec3a5db28de7d5db6d78e38033b80740e49Mathieu Chartier const std::string pretty_type(PrettyTypeOf(o)); 1110e6a8eec3a5db28de7d5db6d78e38033b80740e49Mathieu Chartier os << StringPrintf("<0x%08x> (a %s)", o->IdentityHashCode(), pretty_type.c_str()); 1111d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers } 1112d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers } 1113d803bc7ce255be6c16eaf6a8a58a742515e9da9fIan Rogers os << "\n"; 11144993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 11154993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 111608fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes std::ostream& os; 111708fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes const Thread* thread; 11180878d654e7be8c9666579e22522704d8887415ccIan Rogers const bool can_allocate; 11193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* last_method; 112028ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers int last_line_number; 112128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers int repetition_count; 11228e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes int frame_count; 1123d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes}; 1124d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 112533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogersstatic bool ShouldShowNativeStack(const Thread* thread) 112633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1127aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes ThreadState state = thread->GetState(); 1128aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes 1129aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // In native code somewhere in the VM (one of the kWaitingFor* states)? That's interesting. 1130aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes if (state > kWaiting && state < kStarting) { 1131aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes return true; 1132aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes } 1133aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes 1134aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // In an Object.wait variant or Thread.sleep? That's not interesting. 1135aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes if (state == kTimedWaiting || state == kSleeping || state == kWaiting) { 1136aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes return false; 1137aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes } 1138aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes 11392366f4e4432d8644404de8c9f9d6a8f2f0b329ffChristopher Ferris // Threads with no managed stack frames should be shown. 11402366f4e4432d8644404de8c9f9d6a8f2f0b329ffChristopher Ferris const ManagedStack* managed_stack = thread->GetManagedStack(); 11412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (managed_stack == nullptr || (managed_stack->GetTopQuickFrame() == nullptr && 11422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier managed_stack->GetTopShadowFrame() == nullptr)) { 11432366f4e4432d8644404de8c9f9d6a8f2f0b329ffChristopher Ferris return true; 11442366f4e4432d8644404de8c9f9d6a8f2f0b329ffChristopher Ferris } 11452366f4e4432d8644404de8c9f9d6a8f2f0b329ffChristopher Ferris 1146aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // In some other native method? That's interesting. 1147aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // We don't just check kNative because native methods will be in state kSuspended if they're 1148aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // calling back into the VM, or kBlocked if they're blocked on a monitor, or one of the 1149aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes // thread-startup states if it's early enough in their life cycle (http://b/7432159). 11503d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* current_method = thread->GetCurrentMethod(nullptr); 11510aded089f565008ba5908e395e5914ca4f91f2deDave Allison return current_method != nullptr && current_method->IsNative(); 1152aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes} 1153aef701da38d14bd479cb275f78e2adaa00f1c54aElliott Hughes 1154c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartiervoid Thread::DumpJavaStack(std::ostream& os) const { 11552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // If flip_function is not null, it means we have run a checkpoint 11562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // before the thread wakes up to execute the flip function and the 11572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // thread roots haven't been forwarded. So the following access to 11582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // the roots (locks or methods in the frames) would be bad. Run it 11592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // here. TODO: clean up. 11602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi { 11612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* this_thread = const_cast<Thread*>(this); 11622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Closure* flip_func = this_thread->GetFlipFunction(); 11632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (flip_func != nullptr) { 11642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi flip_func->Run(this_thread); 11652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 11662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 11672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1168986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe // Dumping the Java stack involves the verifier for locks. The verifier operates under the 1169986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe // assumption that there is no exception pending on entry. Thus, stash any pending exception. 1170bef89c910dc40f7e82ee56c3c8e8fdaa0cd5562bMathieu Chartier // Thread::Current() instead of this in case a thread is dumping the stack of another suspended 1171bef89c910dc40f7e82ee56c3c8e8fdaa0cd5562bMathieu Chartier // thread. 117214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray StackHandleScope<1> scope(Thread::Current()); 1173986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe Handle<mirror::Throwable> exc; 1174986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe bool have_exception = false; 1175986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe if (IsExceptionPending()) { 117614691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray exc = scope.NewHandle(GetException()); 1177986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe const_cast<Thread*>(this)->ClearException(); 1178986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe have_exception = true; 1179986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe } 1180986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe 1181700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<Context> context(Context::Create()); 1182c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier StackDumpVisitor dumper(os, const_cast<Thread*>(this), context.get(), 1183c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier !tls32_.throwing_OutOfMemoryError); 1184c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier dumper.WalkStack(); 1185986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe 1186986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe if (have_exception) { 118714691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray const_cast<Thread*>(this)->SetException(exc.Get()); 1188986c6fbb5f65006165f8b7fed1fd105fb3a83bd9Andreas Gampe } 1189c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier} 1190c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier 1191d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughesvoid Thread::DumpStack(std::ostream& os) const { 1192ed1790e83352e54420018d1495eb010f7cd48a64Jeff Hao // TODO: we call this code when dying but may not have suspended the thread ourself. The 1193ed1790e83352e54420018d1495eb010f7cd48a64Jeff Hao // IsSuspended check is therefore racy with the use for dumping (normally we inhibit 1194ed1790e83352e54420018d1495eb010f7cd48a64Jeff Hao // the race with the thread_suspend_count_lock_). 1195eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers bool dump_for_abort = (gAborting > 0); 1196eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers bool safe_to_dump = (this == Thread::Current() || IsSuspended()); 1197eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers if (!kIsDebugBuild) { 1198eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers // We always want to dump the stack for an abort, however, there is no point dumping another 1199eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers // thread's stack in debug builds where we'll hit the not suspended check in the stack walk. 1200eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers safe_to_dump = (safe_to_dump || dump_for_abort); 1201eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers } 1202eef2e54113ba10cd76ddc368b928a2864401700eIan Rogers if (safe_to_dump) { 1203f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers // If we're currently in native code, dump that stack before dumping the managed stack. 1204d090cf4f2420a228251e27dbae600f4f44ae2c57Ian Rogers if (dump_for_abort || ShouldShowNativeStack(this)) { 1205f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers DumpKernelStack(os, GetTid(), " kernel: ", false); 1206b2f5dbb85bef25eb911dbea119ed8d6450fd6f8cAndreas Gampe DumpNativeStack(os, GetTid(), " native: ", GetCurrentMethod(nullptr, !dump_for_abort)); 1207f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers } 1208c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier DumpJavaStack(os); 1209f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers } else { 1210f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers os << "Not able to dump stack of thread that isn't suspended"; 1211f08e473519dc5c7ccb85eb2b333f9d0aff23a329Ian Rogers } 1212e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes} 1213e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 1214be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughesvoid Thread::ThreadExitCallback(void* arg) { 1215be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Thread* self = reinterpret_cast<Thread*>(arg); 1216dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (self->tls32_.thread_exit_check_count == 0) { 1217dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers LOG(WARNING) << "Native thread exiting without having called DetachCurrentThread (maybe it's " 1218dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers "going to use a pthread_key_create destructor?): " << *self; 12190878d654e7be8c9666579e22522704d8887415ccIan Rogers CHECK(is_started_); 12206a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, self), "reattach self"); 1221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers self->tls32_.thread_exit_check_count = 1; 12226a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes } else { 12236a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes LOG(FATAL) << "Native thread exited without calling DetachCurrentThread: " << *self; 12246a607ad0902f3b8478e95d0b6b3e63a538571a3fElliott Hughes } 1225b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 1226b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 1227be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughesvoid Thread::Startup() { 12280878d654e7be8c9666579e22522704d8887415ccIan Rogers CHECK(!is_started_); 12290878d654e7be8c9666579e22522704d8887415ccIan Rogers is_started_ = true; 123000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 12316d69f592696f3bbd3bb0978ae3b25f2c359aac0dBrian Carlstrom // MutexLock to keep annotalysis happy. 12326d69f592696f3bbd3bb0978ae3b25f2c359aac0dBrian Carlstrom // 12332cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Note we use null for the thread because Thread::Current can 12346d69f592696f3bbd3bb0978ae3b25f2c359aac0dBrian Carlstrom // return garbage since (is_started_ == true) and 12356d69f592696f3bbd3bb0978ae3b25f2c359aac0dBrian Carlstrom // Thread::pthread_key_self_ is not yet initialized. 12366d69f592696f3bbd3bb0978ae3b25f2c359aac0dBrian Carlstrom // This was seen on glibc. 12370aded089f565008ba5908e395e5914ca4f91f2deDave Allison MutexLock mu(nullptr, *Locks::thread_suspend_count_lock_); 1238c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers resume_cond_ = new ConditionVariable("Thread resumption condition variable", 1239c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers *Locks::thread_suspend_count_lock_); 124000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 124100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 1242b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Allocate a TLS slot. 1243f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers CHECK_PTHREAD_CALL(pthread_key_create, (&Thread::pthread_key_self_, Thread::ThreadExitCallback), 1244f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers "self key"); 1245b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 1246b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Double-check the TLS slot allocation. 12470aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (pthread_getspecific(pthread_key_self_) != nullptr) { 12480aded089f565008ba5908e395e5914ca4f91f2deDave Allison LOG(FATAL) << "Newly-created pthread TLS slot is not nullptr"; 1249b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 1250038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes} 1251038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes 1252038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughesvoid Thread::FinishStartup() { 1253365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Runtime* runtime = Runtime::Current(); 1254365c10235438607541fa2259a5fec48061b90bd8Ian Rogers CHECK(runtime->IsStarted()); 1255b82b6878fb000d4731063b1bf15c39ff7c50b61fBrian Carlstrom 125601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Finish attaching the main thread. 125700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 1258365c10235438607541fa2259a5fec48061b90bd8Ian Rogers Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup()); 12599a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson 1260af8d15a3267343dec135cc6df1db740c0a5c7b52Elliott Hughes Runtime::Current()->GetClassLinker()->RunRootClinits(); 1261b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro} 1262b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 1263c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughesvoid Thread::Shutdown() { 12640878d654e7be8c9666579e22522704d8887415ccIan Rogers CHECK(is_started_); 12650878d654e7be8c9666579e22522704d8887415ccIan Rogers is_started_ = false; 12668d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes CHECK_PTHREAD_CALL(pthread_key_delete, (Thread::pthread_key_self_), "self key"); 126733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_); 12680aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (resume_cond_ != nullptr) { 12690878d654e7be8c9666579e22522704d8887415ccIan Rogers delete resume_cond_; 12700aded089f565008ba5908e395e5914ca4f91f2deDave Allison resume_cond_ = nullptr; 12710878d654e7be8c9666579e22522704d8887415ccIan Rogers } 1272c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 1273c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 1274dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersThread::Thread(bool daemon) : tls32_(daemon), wait_monitor_(nullptr), interrupted_(false) { 1275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers wait_mutex_ = new Mutex("a thread wait mutex"); 1276dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers wait_cond_ = new ConditionVariable("a thread wait condition variable", *wait_mutex_); 1277dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.instrumentation_stack = new std::deque<instrumentation::InstrumentationStackFrame>; 1278dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.name = new std::string(kThreadNameDuringStartup); 12798ce6b9040747054b444a7fa706503cd257801936Dave Allison tlsPtr_.nested_signal_state = static_cast<jmp_buf*>(malloc(sizeof(jmp_buf))); 1280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1281f5a7a476e7ea63e094ff0f011dccc170607e6f6bElliott Hughes CHECK_EQ((sizeof(Thread) % 4), 0U) << sizeof(Thread); 1282dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.state_and_flags.as_struct.flags = 0; 1283dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.state_and_flags.as_struct.state = kNative; 1284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers memset(&tlsPtr_.held_mutexes[0], 0, sizeof(tlsPtr_.held_mutexes)); 12850651d41e41341fb2e9ef3ee41dc1f1bfc832dbbbMathieu Chartier std::fill(tlsPtr_.rosalloc_runs, 1286e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers tlsPtr_.rosalloc_runs + kNumRosAllocThreadLocalSizeBrackets, 128773d1e17b3afc7d5e56184f90bf819dc64956448aMathieu Chartier gc::allocator::RosAlloc::GetDedicatedFullRun()); 12880aded089f565008ba5908e395e5914ca4f91f2deDave Allison for (uint32_t i = 0; i < kMaxCheckpoints; ++i) { 1289dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.checkpoint_functions[i] = nullptr; 12900aded089f565008ba5908e395e5914ca4f91f2deDave Allison } 12912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi tlsPtr_.flip_function = nullptr; 12922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi tls32_.suspended_at_suspend_check = false; 1293dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 1294dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 12957dc5166ea740359d381097a7ab382c1dd404055fElliott Hughesbool Thread::IsStillStarting() const { 12967dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // You might think you can check whether the state is kStarting, but for much of thread startup, 129780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes // the thread is in kNative; it might also be in kVmWait. 12982cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // You might think you can check whether the peer is null, but the peer is actually created and 12997dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // assigned fairly early on, and needs to be. 13007dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // It turns out that the last thing to change is the thread name; that's a good proxy for "has 13017dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes // this thread _ever_ entered kRunnable". 1302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return (tlsPtr_.jpeer == nullptr && tlsPtr_.opeer == nullptr) || 1303dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers (*tlsPtr_.name == kThreadNameDuringStartup); 13047dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes} 13057dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes 1306d9efea646485fe996c967f4680a3fc4cdc40b251Andreas Gampevoid Thread::AssertPendingException() const { 1307a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier CHECK(IsExceptionPending()) << "Pending exception expected."; 1308a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier} 1309a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier 1310a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartiervoid Thread::AssertPendingOOMException() const { 1311a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier AssertPendingException(); 1312a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier auto* e = GetException(); 1313a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier CHECK_EQ(e->GetClass(), DecodeJObject(WellKnownClasses::java_lang_OutOfMemoryError)->AsClass()) 1314a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier << e->Dump(); 1315d9efea646485fe996c967f4680a3fc4cdc40b251Andreas Gampe} 1316d9efea646485fe996c967f4680a3fc4cdc40b251Andreas Gampe 131700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Thread::AssertNoPendingException() const { 131800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (UNLIKELY(IsExceptionPending())) { 131900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 132014691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray mirror::Throwable* exception = GetException(); 132100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(FATAL) << "No pending exception expected: " << exception->Dump(); 132200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 132300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 132400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 13258d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartiervoid Thread::AssertNoPendingExceptionForNewException(const char* msg) const { 13268d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier if (UNLIKELY(IsExceptionPending())) { 13278d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier ScopedObjectAccess soa(Thread::Current()); 132814691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray mirror::Throwable* exception = GetException(); 1329c114b5fbc91e6d19ef430d9bc3468386ca61b324Ian Rogers LOG(FATAL) << "Throwing new exception '" << msg << "' with unexpected pending exception: " 13308d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier << exception->Dump(); 13318d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier } 13328d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier} 13338d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier 1334bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass MonitorExitVisitor : public SingleRootVisitor { 1335bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 1336bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier explicit MonitorExitVisitor(Thread* self) : self_(self) { } 1337bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 1338bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier // NO_THREAD_SAFETY_ANALYSIS due to MonitorExit. 1339bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::Object* entered_monitor, const RootInfo& info ATTRIBUTE_UNUSED) 1340bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier OVERRIDE NO_THREAD_SAFETY_ANALYSIS { 1341bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (self_->HoldsLock(entered_monitor)) { 1342bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier LOG(WARNING) << "Calling MonitorExit on object " 1343bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier << entered_monitor << " (" << PrettyTypeOf(entered_monitor) << ")" 1344bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier << " left locked by native thread " 1345bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier << *Thread::Current() << " which is detaching"; 1346bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier entered_monitor->MonitorExit(self_); 1347bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 134800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 1349bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 1350bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 1351bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Thread* const self_; 1352bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 135302b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 1354c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughesvoid Thread::Destroy() { 1355120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers Thread* self = this; 1356120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers DCHECK_EQ(self, Thread::Current()); 135702b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 135868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (tlsPtr_.jni_env != nullptr) { 1359bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier { 1360bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ScopedObjectAccess soa(self); 1361bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MonitorExitVisitor visitor(self); 1362bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier // On thread detach, all monitors entered with JNI MonitorEnter are automatically exited. 1363bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier tlsPtr_.jni_env->monitors.VisitRoots(&visitor, RootInfo(kRootVMInternal)); 1364bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 136568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Release locally held global references which releasing may require the mutator lock. 136668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (tlsPtr_.jpeer != nullptr) { 136768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // If pthread_create fails we don't have a jni env here. 136868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.jni_env->DeleteGlobalRef(tlsPtr_.jpeer); 136968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.jpeer = nullptr; 137068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 137168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (tlsPtr_.class_loader_override != nullptr) { 137268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.jni_env->DeleteGlobalRef(tlsPtr_.class_loader_override); 137368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.class_loader_override = nullptr; 137468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 137568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 137668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 1377dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tlsPtr_.opeer != nullptr) { 1378cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedObjectAccess soa(self); 1379120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // We may need to call user-supplied managed code, do this before final clean-up. 1380cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers HandleUncaughtExceptions(soa); 1381cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers RemoveFromThreadGroup(soa); 1382534da072d3db3beecbd74e5aa23d630d73695f2cElliott Hughes 13833c50a4b4ba6d7d9369ee9a0bd6d30bf4c9c79bb0Anwar Ghuloum // this.nativePeer = 0; 1384d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (Runtime::Current()->IsActiveTransaction()) { 1385dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers soa.DecodeField(WellKnownClasses::java_lang_Thread_nativePeer) 1386dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ->SetLong<true>(tlsPtr_.opeer, 0); 1387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 1388dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers soa.DecodeField(WellKnownClasses::java_lang_Thread_nativePeer) 1389dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ->SetLong<false>(tlsPtr_.opeer, 0); 1390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 1391cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers Dbg::PostThreadDeath(self); 139202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 1393cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers // Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone 1394cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers // who is waiting. 13952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* lock = 1396dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers soa.DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(tlsPtr_.opeer); 1397038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // (This conditional is only needed for tests, where Thread.lock won't have been set.) 1398c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (lock != nullptr) { 1399eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 1400eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Object> h_obj(hs.NewHandle(lock)); 1401db2633ce0358c704f97130a94b582602cb01d14aMathieu Chartier ObjectLock<mirror::Object> locker(self, h_obj); 140263e8a68c9a2cdbbe9bfd8d200610119dd359ee59Yevgeny Rouban locker.NotifyAll(); 14035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 140468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.opeer = nullptr; 14055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1406120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 1407a1b94c6d06e3cf2aa4f3aa42a1133995a4d8a1fbHiroshi Yamauchi { 1408a1b94c6d06e3cf2aa4f3aa42a1133995a4d8a1fbHiroshi Yamauchi ScopedObjectAccess soa(self); 1409a1b94c6d06e3cf2aa4f3aa42a1133995a4d8a1fbHiroshi Yamauchi Runtime::Current()->GetHeap()->RevokeThreadLocalBuffers(this); 1410a1b94c6d06e3cf2aa4f3aa42a1133995a4d8a1fbHiroshi Yamauchi } 1411c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes} 141202b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes 1413c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott HughesThread::~Thread() { 141468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers CHECK(tlsPtr_.class_loader_override == nullptr); 141568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers CHECK(tlsPtr_.jpeer == nullptr); 141668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers CHECK(tlsPtr_.opeer == nullptr); 1417dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers bool initialized = (tlsPtr_.jni_env != nullptr); // Did Thread::Init run? 14181efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov if (initialized) { 1419dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers delete tlsPtr_.jni_env; 1420dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env = nullptr; 14211efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov } 1422dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier CHECK_NE(GetState(), kRunnable); 14230aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK_NE(ReadFlag(kCheckpointRequest), true); 1424dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(tlsPtr_.checkpoint_functions[0] == nullptr); 1425dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(tlsPtr_.checkpoint_functions[1] == nullptr); 1426dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(tlsPtr_.checkpoint_functions[2] == nullptr); 14272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi CHECK(tlsPtr_.flip_function == nullptr); 14282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi CHECK_EQ(tls32_.suspended_at_suspend_check, false); 14290aded089f565008ba5908e395e5914ca4f91f2deDave Allison 1430dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier // We may be deleting a still born thread. 1431dbe6f4613ae0161b169f4fca8a616b0b393370abMathieu Chartier SetStateUnsafe(kTerminated); 143285d1545e985ac689db4bad7849880e843707c862Elliott Hughes 143385d1545e985ac689db4bad7849880e843707c862Elliott Hughes delete wait_cond_; 143485d1545e985ac689db4bad7849880e843707c862Elliott Hughes delete wait_mutex_; 143585d1545e985ac689db4bad7849880e843707c862Elliott Hughes 1436dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tlsPtr_.long_jump_context != nullptr) { 1437dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers delete tlsPtr_.long_jump_context; 1438c928de90ad22ecdf83c18a07008409595f13d3b1Ian Rogers } 1439475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes 14401efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov if (initialized) { 14411efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov CleanupCpu(); 14421efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov } 14431efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov 1444597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz if (tlsPtr_.single_step_control != nullptr) { 1445597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz delete tlsPtr_.single_step_control; 1446597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz } 1447dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers delete tlsPtr_.instrumentation_stack; 1448dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers delete tlsPtr_.name; 1449dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers delete tlsPtr_.stack_trace_sample; 14508ce6b9040747054b444a7fa706503cd257801936Dave Allison free(tlsPtr_.nested_signal_state); 1451d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes 145268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers Runtime::Current()->GetHeap()->AssertThreadLocalBuffersAreRevoked(this); 1453cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 1454d8af1592a97f7447ecf93f85098cb36340ab0fe2Elliott Hughes TearDownAlternateSignalStack(); 1455c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 1456c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 1457cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogersvoid Thread::HandleUncaughtExceptions(ScopedObjectAccess& soa) { 1458accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes if (!IsExceptionPending()) { 1459accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes return; 1460accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes } 1461dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ScopedLocalRef<jobject> peer(tlsPtr_.jni_env, soa.AddLocalReference<jobject>(tlsPtr_.opeer)); 1462cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedThreadStateChange tsc(this, kNative); 1463120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 1464accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Get and clear the exception. 1465dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ScopedLocalRef<jthrowable> exception(tlsPtr_.jni_env, tlsPtr_.jni_env->ExceptionOccurred()); 1466dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env->ExceptionClear(); 1467accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1468accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // If the thread has its own handler, use that. 1469dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ScopedLocalRef<jobject> handler(tlsPtr_.jni_env, 1470dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env->GetObjectField(peer.get(), 1471dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers WellKnownClasses::java_lang_Thread_uncaughtHandler)); 14720aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (handler.get() == nullptr) { 1473accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Otherwise use the thread group's default handler. 1474dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers handler.reset(tlsPtr_.jni_env->GetObjectField(peer.get(), 1475dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers WellKnownClasses::java_lang_Thread_group)); 1476accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes } 1477accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1478accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Call the handler. 1479dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env->CallVoidMethod(handler.get(), 1480c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas Gampe WellKnownClasses::java_lang_Thread__UncaughtExceptionHandler_uncaughtException, 1481dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers peer.get(), exception.get()); 1482accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1483accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // If the handler threw, clear that exception too. 1484dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env->ExceptionClear(); 1485a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes} 1486a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes 1487cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogersvoid Thread::RemoveFromThreadGroup(ScopedObjectAccess& soa) { 14884514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom // this.group.removeThread(this); 14894514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom // group can be null if we're in the compiler or a test. 1490dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers mirror::Object* ogroup = soa.DecodeField(WellKnownClasses::java_lang_Thread_group) 1491dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ->GetObject(tlsPtr_.opeer); 14920aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (ogroup != nullptr) { 1493cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedLocalRef<jobject> group(soa.Env(), soa.AddLocalReference<jobject>(ogroup)); 1494dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ScopedLocalRef<jobject> peer(soa.Env(), soa.AddLocalReference<jobject>(tlsPtr_.opeer)); 1495cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers ScopedThreadStateChange tsc(soa.Self(), kNative); 1496dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.jni_env->CallVoidMethod(group.get(), 1497dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers WellKnownClasses::java_lang_ThreadGroup_removeThread, 1498dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers peer.get()); 14994514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom } 15004514d3c0e69a49f5dbe19138330a2bb2aee36d63Brian Carlstrom} 1501accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1502eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiersize_t Thread::NumHandleReferences() { 1503a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers size_t count = 0; 1504c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers for (HandleScope* cur = tlsPtr_.top_handle_scope; cur != nullptr; cur = cur->GetLink()) { 1505a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers count += cur->NumberOfReferences(); 1506a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 1507a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers return count; 1508a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers} 1509a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers 1510eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartierbool Thread::HandleScopeContains(jobject obj) const { 1511eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackReference<mirror::Object>* hs_entry = 1512ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers reinterpret_cast<StackReference<mirror::Object>*>(obj); 1513c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers for (HandleScope* cur = tlsPtr_.top_handle_scope; cur!= nullptr; cur = cur->GetLink()) { 1514eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (cur->Contains(hs_entry)) { 1515a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers return true; 1516a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 1517a8cd9f4a849835af7856f9c9782ea59e11ddef85Ian Rogers } 1518eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // JNI code invoked from portable code uses shadow frames rather than the handle scope. 1519eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier return tlsPtr_.managed_stack.ShadowFramesContain(hs_entry); 152028f1a147d77ec772db98bed890b50a9ddcff2365TDYa} 152128f1a147d77ec772db98bed890b50a9ddcff2365TDYa 1522bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Thread::HandleScopeVisitRoots(RootVisitor* visitor, uint32_t thread_id) { 15234809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor( 15244809d0a8a5fca85a67dd0588ead5dfbd0f1acf96Mathieu Chartier visitor, RootInfo(kRootNativeStack, thread_id)); 1525eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier for (HandleScope* cur = tlsPtr_.top_handle_scope; cur; cur = cur->GetLink()) { 1526bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier for (size_t j = 0, count = cur->NumberOfReferences(); j < count; ++j) { 15279086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // GetReference returns a pointer to the stack reference within the handle scope. If this 15289086b65b2ad35dd39a8afc62d535be8217208d08Mathieu Chartier // needs to be updated, it will be done by the root visitor. 1529bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier buffered_visitor.VisitRootIfNonNull(cur->GetHandle(j).GetReference()); 15308dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao } 15318dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao } 15328dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao} 15338dfc9d551a9603eb8bc8463621b7bc73c3035169Shih-wei Liao 15342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::Object* Thread::DecodeJObject(jobject obj) const { 15350aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (obj == nullptr) { 15360aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 1537408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 1538408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectRef ref = reinterpret_cast<IndirectRef>(obj); 1539408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers IndirectRefKind kind = GetIndirectRefKind(ref); 15402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* result; 1541c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers bool expect_null = false; 15424f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers // The "kinds" below are sorted by the frequency we expect to encounter them. 15434f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers if (kind == kLocal) { 1544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers IndirectReferenceTable& locals = tlsPtr_.jni_env->locals; 1545196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi // Local references do not need a read barrier. 1546196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi result = locals.Get<kWithoutReadBarrier>(ref); 1547eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier } else if (kind == kHandleScopeOrInvalid) { 1548ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // TODO: make stack indirect reference table lookup more efficient. 1549eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Check if this is a local reference in the handle scope. 1550eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (LIKELY(HandleScopeContains(obj))) { 1551eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Read from handle scope. 1552ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers result = reinterpret_cast<StackReference<mirror::Object>*>(obj)->AsMirrorPtr(); 1553c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier VerifyObject(result); 1554408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } else { 1555c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers tlsPtr_.jni_env->vm->JniAbortF(nullptr, "use of invalid jobject %p", obj); 1556c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers expect_null = true; 1557c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers result = nullptr; 1558408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 15594f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers } else if (kind == kGlobal) { 156068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers result = tlsPtr_.jni_env->vm->DecodeGlobal(const_cast<Thread*>(this), ref); 15614f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers } else { 15624f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers DCHECK_EQ(kind, kWeakGlobal); 156368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers result = tlsPtr_.jni_env->vm->DecodeWeakGlobal(const_cast<Thread*>(this), ref); 1564c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers if (Runtime::Current()->IsClearedJniWeakGlobal(result)) { 15652cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // This is a special case where it's okay to return null. 1566c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers expect_null = true; 1567c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers result = nullptr; 15684f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers } 1569408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 1570408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 1571c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers if (UNLIKELY(!expect_null && result == nullptr)) { 157268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.jni_env->vm->JniAbortF(nullptr, "use of deleted %s %p", 157368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ToStr<IndirectRefKind>(kind).c_str(), obj); 1574408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers } 1575408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers return result; 1576408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers} 1577408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers 157881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers// Implements java.lang.Thread.interrupted. 157981d425b0b232962441616f8b14f73620bffef5e5Ian Rogersbool Thread::Interrupted() { 158050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), *wait_mutex_); 1581dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers bool interrupted = IsInterruptedLocked(); 1582dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers SetInterruptedLocked(false); 158381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers return interrupted; 158481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers} 158581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 158681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers// Implements java.lang.Thread.isInterrupted. 158781d425b0b232962441616f8b14f73620bffef5e5Ian Rogersbool Thread::IsInterrupted() { 158850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), *wait_mutex_); 1589dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return IsInterruptedLocked(); 159081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers} 159181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 1592dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid Thread::Interrupt(Thread* self) { 1593c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers MutexLock mu(self, *wait_mutex_); 159481d425b0b232962441616f8b14f73620bffef5e5Ian Rogers if (interrupted_) { 159581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers return; 159681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 159781d425b0b232962441616f8b14f73620bffef5e5Ian Rogers interrupted_ = true; 1598c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers NotifyLocked(self); 159981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers} 160081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 160181d425b0b232962441616f8b14f73620bffef5e5Ian Rogersvoid Thread::Notify() { 1602c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers Thread* self = Thread::Current(); 1603c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers MutexLock mu(self, *wait_mutex_); 1604c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers NotifyLocked(self); 160581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers} 160681d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 1607c604d731730b43231f63040c8db1d58304da0cf3Ian Rogersvoid Thread::NotifyLocked(Thread* self) { 16080aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (wait_monitor_ != nullptr) { 1609c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers wait_cond_->Signal(self); 161081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers } 161181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers} 161281d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 161368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersvoid Thread::SetClassLoaderOverride(jobject class_loader_override) { 161468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (tlsPtr_.class_loader_override != nullptr) { 161568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers GetJniEnv()->DeleteGlobalRef(tlsPtr_.class_loader_override); 161668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 161768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers tlsPtr_.class_loader_override = GetJniEnv()->NewGlobalRef(class_loader_override); 161868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers} 161968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 16200399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass CountStackDepthVisitor : public StackVisitor { 16219b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 162293ba893c20532990a430741e0a97212900094e8cBrian Carlstrom explicit CountStackDepthVisitor(Thread* thread) 1623b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 16248e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), 162508fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes depth_(0), skip_depth_(0), skipping_(true) {} 1626d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes 1627b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 162829f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // We want to skip frames up to and including the exception's constructor. 16299086572fa809d1a19d886b467e4da3ce42016982Ian Rogers // Note we also skip the frame if it doesn't have a method (namely the callee 16309086572fa809d1a19d886b467e4da3ce42016982Ian Rogers // save frame) 16313d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* m = GetMethod(); 16320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (skipping_ && !m->IsRuntimeMethod() && 16332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers !mirror::Throwable::GetJavaLangThrowable()->IsAssignableFrom(m->GetDeclaringClass())) { 163429f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes skipping_ = false; 163529f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 163629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes if (!skipping_) { 16370399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (!m->IsRuntimeMethod()) { // Ignore runtime frames (in particular callee save). 16386b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers ++depth_; 16396b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers } 164029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } else { 164129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes ++skip_depth_; 164229f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 1643530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 16449b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 16459b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 16469b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao int GetDepth() const { 1647aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers return depth_; 16489b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 16499b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 165029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int GetSkipDepth() const { 165129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes return skip_depth_; 165229f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 165329f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes 16549b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao private: 1655aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers uint32_t depth_; 165629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes uint32_t skip_depth_; 165729f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes bool skipping_; 16589b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao}; 16599b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 1660ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertztemplate<bool kTransactionActive> 16610399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass BuildInternalStackTraceVisitor : public StackVisitor { 16629b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao public: 16637a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers explicit BuildInternalStackTraceVisitor(Thread* self, Thread* thread, int skip_depth) 16648e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), 16658e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray self_(self), 16668e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray skip_depth_(skip_depth), 16678e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray count_(0), 16683d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier trace_(nullptr), 16693d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier pointer_size_(Runtime::Current()->GetClassLinker()->GetImagePointerSize()) {} 1670283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers 16711f5393447b9f45be7918042d9ee7b521376de866Ian Rogers bool Init(int depth) 1672b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16733d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // Allocate method trace with format [method pointers][pcs]. 16743d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* cl = Runtime::Current()->GetClassLinker(); 16753d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier trace_ = cl->AllocPointerArray(self_, depth * 2); 16763d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier if (trace_ == nullptr) { 16773d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier self_->AssertPendingOOMException(); 1678283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return false; 1679726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes } 16803d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // If We are called from native, use non-transactional mode. 168152673ffae0025d86f4023735581f19ebcc477487Ian Rogers const char* last_no_suspend_cause = 16821f5393447b9f45be7918042d9ee7b521376de866Ian Rogers self_->StartAssertNoThreadSuspension("Building internal stack trace"); 16830aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(last_no_suspend_cause == nullptr) << last_no_suspend_cause; 1684283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers return true; 16859b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 16869b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 16870399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers virtual ~BuildInternalStackTraceVisitor() { 16883d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier if (trace_ != nullptr) { 16890aded089f565008ba5908e395e5914ca4f91f2deDave Allison self_->EndAssertNoThreadSuspension(nullptr); 169052673ffae0025d86f4023735581f19ebcc477487Ian Rogers } 16910399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 16929b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 1693b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16943d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier if (trace_ == nullptr) { 16957934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return true; // We're probably trying to fillInStackTrace for an OutOfMemoryError. 1696726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes } 169729f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes if (skip_depth_ > 0) { 169829f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes skip_depth_--; 1699530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 170029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes } 17013d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* m = GetMethod(); 17020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers if (m->IsRuntimeMethod()) { 17030399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return true; // Ignore runtime frames (in particular callee save). 17046b0870dfaaa2e69a900ad7ed88e4e1d3697445aaIan Rogers } 17053d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier trace_->SetElementPtrSize<kTransactionActive>( 17063d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier count_, m, pointer_size_); 17073d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier trace_->SetElementPtrSize<kTransactionActive>( 17083d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier trace_->GetLength() / 2 + count_, m->IsProxyMethod() ? DexFile::kDexNoIndex : GetDexPc(), 17093d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier pointer_size_); 1710aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers ++count_; 1711530fa005e2944d3b12712f80d974f0e753f568efElliott Hughes return true; 17129b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 17139b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 17143d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier mirror::PointerArray* GetInternalStackTrace() const { 17153d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier return trace_; 17169b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao } 17179b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 17189b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao private: 17191f5393447b9f45be7918042d9ee7b521376de866Ian Rogers Thread* const self_; 172029f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes // How many more frames to skip. 172129f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int32_t skip_depth_; 17220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Current position down stack trace. 1723aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers uint32_t count_; 17243d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // An array of the methods on the stack, the last entries are the dex PCs. 17253d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier mirror::PointerArray* trace_; 17263d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // For cross compilation. 17273d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier size_t pointer_size_; 17289b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao}; 17299b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao 1730ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertztemplate<bool kTransactionActive> 17312b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartierjobject Thread::CreateInternalStackTrace(const ScopedObjectAccessAlreadyRunnable& soa) const { 1732aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Compute depth of stack 17337a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers CountStackDepthVisitor count_visitor(const_cast<Thread*>(this)); 17340399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers count_visitor.WalkStack(); 17359b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao int32_t depth = count_visitor.GetDepth(); 173629f2742a478e4f5bd2ec7473410c5e5e7134a6f2Elliott Hughes int32_t skip_depth = count_visitor.GetSkipDepth(); 17374417536522fd2a9d8215d8672331984769c9520bShih-wei Liao 17381f5393447b9f45be7918042d9ee7b521376de866Ian Rogers // Build internal stack trace. 1739ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertz BuildInternalStackTraceVisitor<kTransactionActive> build_trace_visitor(soa.Self(), 1740ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertz const_cast<Thread*>(this), 1741ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertz skip_depth); 17421f5393447b9f45be7918042d9ee7b521376de866Ian Rogers if (!build_trace_visitor.Init(depth)) { 17430aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; // Allocation failed. 1744283ed0d9db3084d0fee46d47cd73bf84bd0cfc16Ian Rogers } 17450399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers build_trace_visitor.WalkStack(); 17463d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier mirror::PointerArray* trace = build_trace_visitor.GetInternalStackTrace(); 17477a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers if (kIsDebugBuild) { 17483d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // Second half is dex PCs. 17493d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier for (uint32_t i = 0; i < static_cast<uint32_t>(trace->GetLength() / 2); ++i) { 17503d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* method = trace->GetElementPtrSize<ArtMethod*>( 17513d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier i, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 17523d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier CHECK(method != nullptr); 17537a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers } 17547a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers } 17553d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier return soa.AddLocalReference<jobject>(trace); 1756aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers} 17572b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartiertemplate jobject Thread::CreateInternalStackTrace<false>( 17582b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier const ScopedObjectAccessAlreadyRunnable& soa) const; 17592b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartiertemplate jobject Thread::CreateInternalStackTrace<true>( 17602b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier const ScopedObjectAccessAlreadyRunnable& soa) const; 17612b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier 17627642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffraybool Thread::IsExceptionThrownByCurrentMethod(mirror::Throwable* exception) const { 17637642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray CountStackDepthVisitor count_visitor(const_cast<Thread*>(this)); 17647642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray count_visitor.WalkStack(); 17657642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray return count_visitor.GetDepth() == exception->GetStackDepth(); 17667642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray} 17677642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray 17682b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierjobjectArray Thread::InternalStackTraceToStackTraceElementArray( 17692b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier const ScopedObjectAccessAlreadyRunnable& soa, jobject internal, jobjectArray output_array, 17702b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier int* stack_depth) { 1771aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Decode the internal stack trace into the depth, method trace and PC trace 17723d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier int32_t depth = soa.Decode<mirror::PointerArray*>(internal)->GetLength() / 2; 1773aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers 17743d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* cl = Runtime::Current()->GetClassLinker(); 1775aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers 177601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes jobjectArray result; 1777530825ba92e317822116efffd470577ddfd142d4Mathieu Chartier 17780aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (output_array != nullptr) { 177901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Reuse the array we were given. 178001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes result = output_array; 178101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // ...adjusting the number of frames we'll write to not exceed the array length. 1782530825ba92e317822116efffd470577ddfd142d4Mathieu Chartier const int32_t traces_length = 1783530825ba92e317822116efffd470577ddfd142d4Mathieu Chartier soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->GetLength(); 1784530825ba92e317822116efffd470577ddfd142d4Mathieu Chartier depth = std::min(depth, traces_length); 178501158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } else { 178601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes // Create java_trace array and place in local reference table 1787530825ba92e317822116efffd470577ddfd142d4Mathieu Chartier mirror::ObjectArray<mirror::StackTraceElement>* java_traces = 17883d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier cl->AllocStackTraceElementArray(soa.Self(), depth); 17890aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (java_traces == nullptr) { 17900aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 179130646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 179200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers result = soa.AddLocalReference<jobjectArray>(java_traces); 179301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } 179401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 17950aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (stack_depth != nullptr) { 179601158d7a57c8321370667a6045220237d16e0da8Elliott Hughes *stack_depth = depth; 179701158d7a57c8321370667a6045220237d16e0da8Elliott Hughes } 179855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 17999b576b4ed1dbe035952f3106d8f4b6993125ed6fShih-wei Liao for (int32_t i = 0; i < depth; ++i) { 18003d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* method_trace = soa.Decode<mirror::PointerArray*>(internal); 1801aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers // Prepare parameters for StackTraceElement(String cls, String method, String file, int line) 18023d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method = method_trace->GetElementPtrSize<ArtMethod*>(i, sizeof(void*)); 18033d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier uint32_t dex_pc = method_trace->GetElementPtrSize<uint32_t>( 18043d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier i + method_trace->GetLength() / 2, sizeof(void*)); 1805228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao int32_t line_number; 1806eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<3> hs(soa.Self()); 1807eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier auto class_name_object(hs.NewHandle<mirror::String>(nullptr)); 1808eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier auto source_name_object(hs.NewHandle<mirror::String>(nullptr)); 1809228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao if (method->IsProxyMethod()) { 1810228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao line_number = -1; 1811eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier class_name_object.Assign(method->GetDeclaringClass()->GetName()); 1812228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao // source_name_object intentionally left null for proxy methods 1813228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao } else { 1814bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier line_number = method->GetLineNumFromDexPC(dex_pc); 1815228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao // Allocate element, potentially triggering GC 1816228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao // TODO: reuse class_name_object via Class::name_? 1817bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* descriptor = method->GetDeclaringClassDescriptor(); 18187c6aca27dd2df58ac3d83a93ec5848e2b7d3159aBrian Carlstrom CHECK(descriptor != nullptr); 1819228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao std::string class_name(PrettyDescriptor(descriptor)); 18203d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier class_name_object.Assign( 18213d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier mirror::String::AllocFromModifiedUtf8(soa.Self(), class_name.c_str())); 1822eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (class_name_object.Get() == nullptr) { 18233d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier soa.Self()->AssertPendingOOMException(); 18247c6aca27dd2df58ac3d83a93ec5848e2b7d3159aBrian Carlstrom return nullptr; 1825228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao } 1826bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* source_file = method->GetDeclaringClassSourceFile(); 18277c6aca27dd2df58ac3d83a93ec5848e2b7d3159aBrian Carlstrom if (source_file != nullptr) { 1828eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier source_name_object.Assign(mirror::String::AllocFromModifiedUtf8(soa.Self(), source_file)); 1829eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (source_name_object.Get() == nullptr) { 18303d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier soa.Self()->AssertPendingOOMException(); 18317c6aca27dd2df58ac3d83a93ec5848e2b7d3159aBrian Carlstrom return nullptr; 18327c6aca27dd2df58ac3d83a93ec5848e2b7d3159aBrian Carlstrom } 1833228d6b8a4f0a21c1e9b2372c3104ce4ee19f65b4Jeff Hao } 183440381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom } 18353d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier const char* method_name = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetName(); 18360aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(method_name != nullptr); 1837eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::String> method_name_object( 1838eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), method_name))); 1839eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (method_name_object.Get() == nullptr) { 18400aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 18416d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers } 1842590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier mirror::StackTraceElement* obj = mirror::StackTraceElement::Alloc( 1843590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier soa.Self(), class_name_object, method_name_object, source_name_object, line_number); 18440aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (obj == nullptr) { 18450aded089f565008ba5908e395e5914ca4f91f2deDave Allison return nullptr; 184630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1847d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We are called from native: use non-transactional mode. 1848d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->Set<false>(i, obj); 184955df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao } 1850aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers return result; 185155df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao} 185255df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao 18530aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffrayvoid Thread::ThrowNewExceptionF(const char* exception_class_descriptor, const char* fmt, ...) { 1854a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_list args; 1855a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_start(args, fmt); 18560aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNewExceptionV(exception_class_descriptor, fmt, args); 1857a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes va_end(args); 18584a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes} 18594a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes 18600aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffrayvoid Thread::ThrowNewExceptionV(const char* exception_class_descriptor, 186162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const char* fmt, va_list ap) { 18624a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes std::string msg; 18634a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes StringAppendV(&msg, fmt, ap); 18640aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNewException(exception_class_descriptor, msg.c_str()); 18655cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes} 186637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 18670aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffrayvoid Thread::ThrowNewException(const char* exception_class_descriptor, 186862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const char* msg) { 18698d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier // Callers should either clear or call ThrowNewWrappedException. 18708d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier AssertNoPendingExceptionForNewException(msg); 18710aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNewWrappedException(exception_class_descriptor, msg); 187262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 187362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1874ee0770379ab3e328fdd5a733e62f05b9f5216e38Nicolas Geoffraystatic mirror::ClassLoader* GetCurrentClassLoader(Thread* self) 187514691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 18763d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method = self->GetCurrentMethod(nullptr); 1877ee0770379ab3e328fdd5a733e62f05b9f5216e38Nicolas Geoffray return method != nullptr 1878ee0770379ab3e328fdd5a733e62f05b9f5216e38Nicolas Geoffray ? method->GetDeclaringClass()->GetClassLoader() 187914691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray : nullptr; 188014691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray} 188114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray 18820aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffrayvoid Thread::ThrowNewWrappedException(const char* exception_class_descriptor, 188362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const char* msg) { 188462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DCHECK_EQ(this, Thread::Current()); 188553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedObjectAccessUnchecked soa(this); 188614691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray StackHandleScope<3> hs(soa.Self()); 1887ee0770379ab3e328fdd5a733e62f05b9f5216e38Nicolas Geoffray Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetCurrentClassLoader(soa.Self()))); 188814691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray ScopedLocalRef<jobject> cause(GetJniEnv(), soa.AddLocalReference<jobject>(GetException())); 188962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ClearException(); 189062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Runtime* runtime = Runtime::Current(); 18913d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* cl = runtime->GetClassLinker(); 1892eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> exception_class( 18933d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier hs.NewHandle(cl->FindClass(this, exception_class_descriptor, class_loader))); 1894eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (UNLIKELY(exception_class.Get() == nullptr)) { 189530646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes CHECK(IsExceptionPending()); 189662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOG(ERROR) << "No exception class " << PrettyDescriptor(exception_class_descriptor); 189730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return; 189830646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 189962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 19007b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (UNLIKELY(!runtime->GetClassLinker()->EnsureInitialized(soa.Self(), exception_class, true, 19017b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers true))) { 190262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DCHECK(IsExceptionPending()); 190362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return; 190462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 190562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DCHECK(!runtime->IsStarted() || exception_class->IsThrowableClass()); 1906eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Throwable> exception( 1907eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier hs.NewHandle(down_cast<mirror::Throwable*>(exception_class->AllocObject(this)))); 190862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1909590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // If we couldn't allocate the exception, throw the pre-allocated out of memory exception. 1910eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier if (exception.Get() == nullptr) { 191114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray SetException(Runtime::Current()->GetPreAllocatedOutOfMemoryError()); 1912590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return; 1913590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 1914590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 191562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Choose an appropriate constructor and set up the arguments. 191662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const char* signature; 191753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedLocalRef<jstring> msg_string(GetJniEnv(), nullptr); 19180aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (msg != nullptr) { 191962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Ensure we remember this and the method over the String allocation. 192053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers msg_string.reset( 192153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers soa.AddLocalReference<jstring>(mirror::String::AllocFromModifiedUtf8(this, msg))); 19220aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (UNLIKELY(msg_string.get() == nullptr)) { 192362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers CHECK(IsExceptionPending()); // OOME. 192462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return; 192562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 19260aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (cause.get() == nullptr) { 192762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers signature = "(Ljava/lang/String;)V"; 1928ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } else { 192962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V"; 193062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 193162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 19320aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (cause.get() == nullptr) { 193362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers signature = "()V"; 193462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 193562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers signature = "(Ljava/lang/Throwable;)V"; 1936ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } 1937ebd1fd233c8e14f50844f15109ccd50b27079722Brian Carlstrom } 19383d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* exception_init_method = 19393d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier exception_class->FindDeclaredDirectMethod("<init>", signature, cl->GetImagePointerSize()); 194062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 19410aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(exception_init_method != nullptr) << "No <init>" << signature << " in " 194262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << PrettyDescriptor(exception_class_descriptor); 194362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 194462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (UNLIKELY(!runtime->IsStarted())) { 194562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Something is trying to throw an exception without a started runtime, which is the common 194662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // case in the compiler. We won't be able to invoke the constructor of the exception, so set 194762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // the exception fields directly. 19480aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (msg != nullptr) { 194953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers exception->SetDetailMessage(down_cast<mirror::String*>(DecodeJObject(msg_string.get()))); 195062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 19510aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (cause.get() != nullptr) { 195253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers exception->SetCause(down_cast<mirror::Throwable*>(DecodeJObject(cause.get()))); 195362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 1954c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers ScopedLocalRef<jobject> trace(GetJniEnv(), 1955c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers Runtime::Current()->IsActiveTransaction() 1956c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers ? CreateInternalStackTrace<true>(soa) 1957c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers : CreateInternalStackTrace<false>(soa)); 1958c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers if (trace.get() != nullptr) { 1959c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers exception->SetStackState(down_cast<mirror::Throwable*>(DecodeJObject(trace.get()))); 1960c45b8b582be5c98941ca3869fcdc9a08d520da41Ian Rogers } 196114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray SetException(exception.Get()); 196262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 196353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jvalue jv_args[2]; 196453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers size_t i = 0; 196553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 19660aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (msg != nullptr) { 196753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jv_args[i].l = msg_string.get(); 196853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ++i; 196962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 19700aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (cause.get() != nullptr) { 197153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jv_args[i].l = cause.get(); 197253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ++i; 197362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 197415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao ScopedLocalRef<jobject> ref(soa.Env(), soa.AddLocalReference<jobject>(exception.Get())); 197515e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao InvokeWithJValues(soa, ref.get(), soa.EncodeMethod(exception_init_method), jv_args); 197662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (LIKELY(!IsExceptionPending())) { 197714691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray SetException(exception.Get()); 197862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 197930646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 1980a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes} 1981a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes 19822ced6a534157d5d963693346904389c19775d2daElliott Hughesvoid Thread::ThrowOutOfMemoryError(const char* msg) { 1983e4301ffb56f9be6f6c2640bfb1870b74f4a37ad2Andreas Gampe LOG(WARNING) << StringPrintf("Throwing OutOfMemoryError \"%s\"%s", 1984dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers msg, (tls32_.throwing_OutOfMemoryError ? " (recursive case)" : "")); 1985dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (!tls32_.throwing_OutOfMemoryError) { 1986dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.throwing_OutOfMemoryError = true; 19870aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNewException("Ljava/lang/OutOfMemoryError;", msg); 1988dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tls32_.throwing_OutOfMemoryError = false; 1989418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes } else { 1990e4301ffb56f9be6f6c2640bfb1870b74f4a37ad2Andreas Gampe Dump(LOG(WARNING)); // The pre-allocated OOME has no stack, so help out and log one. 199114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray SetException(Runtime::Current()->GetPreAllocatedOutOfMemoryError()); 1992418dfe7849f45535b5388a91bd7a16cfc20a612bElliott Hughes } 199379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes} 199479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 1995498508c1187dc07d3eae5476784cde20f5224d93Elliott HughesThread* Thread::CurrentFromGdb() { 1996accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes return Thread::Current(); 1997accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes} 1998accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 1999accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughesvoid Thread::DumpFromGdb() const { 20006b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom std::ostringstream ss; 20016b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom Dump(ss); 2002955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string str(ss.str()); 20036b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom // log to stderr for debugging command line processes 20046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom std::cerr << str; 20056b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom#ifdef HAVE_ANDROID_OS 20066b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom // log to logcat for debugging frameworks processes 20076b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom LOG(INFO) << str; 20086b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom#endif 2009accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes} 2010accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes 2011dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Explicitly instantiate 32 and 64bit thread offset dumping support. 2012dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogerstemplate void Thread::DumpThreadOffset<4>(std::ostream& os, uint32_t offset); 2013dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogerstemplate void Thread::DumpThreadOffset<8>(std::ostream& os, uint32_t offset); 201498e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes 2015dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogerstemplate<size_t ptr_size> 2016dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersvoid Thread::DumpThreadOffset(std::ostream& os, uint32_t offset) { 2017dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#define DO_THREAD_OFFSET(x, y) \ 2018dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (offset == x.Uint32Value()) { \ 2019dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << y; \ 2020f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom return; \ 2021f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom } 2022dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(ThreadFlagsOffset<ptr_size>(), "state_and_flags") 2023dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(CardTableOffset<ptr_size>(), "card_table") 2024dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(ExceptionOffset<ptr_size>(), "exception") 2025dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(PeerOffset<ptr_size>(), "peer"); 2026dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(JniEnvOffset<ptr_size>(), "jni_env") 2027dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(SelfOffset<ptr_size>(), "self") 2028dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(StackEndOffset<ptr_size>(), "stack_end") 2029dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(ThinLockIdOffset<ptr_size>(), "thin_lock_thread_id") 2030dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(TopOfManagedStackOffset<ptr_size>(), "top_quick_frame_method") 2031dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(TopShadowFrameOffset<ptr_size>(), "top_shadow_frame") 2032eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier DO_THREAD_OFFSET(TopHandleScopeOffset<ptr_size>(), "top_handle_scope") 2033dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DO_THREAD_OFFSET(ThreadSuspendTriggerOffset<ptr_size>(), "suspend_trigger") 203428fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes#undef DO_THREAD_OFFSET 203598e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes 2036dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#define INTERPRETER_ENTRY_POINT_INFO(x) \ 2037dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (INTERPRETER_ENTRYPOINT_OFFSET(ptr_size, x).Uint32Value() == offset) { \ 2038dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << #x; \ 2039dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return; \ 204098e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes } 2041dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers INTERPRETER_ENTRY_POINT_INFO(pInterpreterToInterpreterBridge) 2042dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers INTERPRETER_ENTRY_POINT_INFO(pInterpreterToCompiledCodeBridge) 2043dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#undef INTERPRETER_ENTRY_POINT_INFO 2044dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 2045dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#define JNI_ENTRY_POINT_INFO(x) \ 2046dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (JNI_ENTRYPOINT_OFFSET(ptr_size, x).Uint32Value() == offset) { \ 2047dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << #x; \ 2048dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return; \ 2049dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 2050dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers JNI_ENTRY_POINT_INFO(pDlsymLookup) 2051dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#undef JNI_ENTRY_POINT_INFO 2052dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 2053dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#define QUICK_ENTRY_POINT_INFO(x) \ 2054dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (QUICK_ENTRYPOINT_OFFSET(ptr_size, x).Uint32Value() == offset) { \ 2055dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers os << #x; \ 2056dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return; \ 2057dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 2058dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocArray) 2059dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocArrayResolved) 2060dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocArrayWithAccessCheck) 2061dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocObject) 2062dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocObjectResolved) 2063dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocObjectInitialized) 2064dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAllocObjectWithAccessCheck) 2065dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCheckAndAllocArray) 2066dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCheckAndAllocArrayWithAccessCheck) 2067848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pAllocStringFromBytes) 2068848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pAllocStringFromChars) 2069848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pAllocStringFromString) 2070dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInstanceofNonTrivial) 2071dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCheckCast) 2072dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInitializeStaticStorage) 2073dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInitializeTypeAndVerifyAccess) 2074dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInitializeType) 2075dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pResolveString) 207637f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pSet8Instance) 207737f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pSet8Static) 207837f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pSet16Instance) 207937f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pSet16Static) 2080dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSet32Instance) 2081dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSet32Static) 2082dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSet64Instance) 2083dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSet64Static) 2084dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSetObjInstance) 2085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pSetObjStatic) 208637f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetByteInstance) 208737f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetBooleanInstance) 208837f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetByteStatic) 208937f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetBooleanStatic) 209037f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetShortInstance) 209137f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetCharInstance) 209237f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetShortStatic) 209337f05ef45e0393de812d51261dc293240c17294dFred Shih QUICK_ENTRY_POINT_INFO(pGetCharStatic) 2094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGet32Instance) 2095dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGet32Static) 2096dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGet64Instance) 2097dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGet64Static) 2098dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGetObjInstance) 2099dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pGetObjStatic) 2100dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAputObjectWithNullAndBoundCheck) 2101dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAputObjectWithBoundCheck) 2102dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pAputObject) 2103dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pHandleFillArrayData) 2104dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodStart) 2105dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodStartSynchronized) 2106dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodEnd) 2107dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodEndSynchronized) 2108dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodEndWithReference) 2109dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pJniMethodEndWithReferenceSynchronized) 2110dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pQuickGenericJniTrampoline) 2111dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pLockObject) 2112dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pUnlockObject) 2113dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCmpgDouble) 2114dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCmpgFloat) 2115dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCmplDouble) 2116dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pCmplFloat) 2117dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pFmod) 2118dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pL2d) 2119dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pFmodf) 2120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pL2f) 2121dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pD2iz) 2122dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pF2iz) 2123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pIdivmod) 2124dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pD2l) 2125dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pF2l) 2126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pLdiv) 2127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pLmod) 2128dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pLmul) 2129dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pShlLong) 2130dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pShrLong) 2131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pUshrLong) 2132dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pIndexOf) 2133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pStringCompareTo) 2134dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pMemcpy) 2135dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pQuickImtConflictTrampoline) 2136dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pQuickResolutionTrampoline) 2137dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pQuickToInterpreterBridge) 2138dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInvokeDirectTrampolineWithAccessCheck) 2139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInvokeInterfaceTrampolineWithAccessCheck) 2140dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInvokeStaticTrampolineWithAccessCheck) 2141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInvokeSuperTrampolineWithAccessCheck) 2142dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pInvokeVirtualTrampolineWithAccessCheck) 2143dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pTestSuspend) 2144dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pDeliverException) 2145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pThrowArrayBounds) 2146dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pThrowDivZero) 2147dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pThrowNoSuchMethod) 2148dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pThrowNullPointer) 2149dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers QUICK_ENTRY_POINT_INFO(pThrowStackOverflow) 2150d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang QUICK_ENTRY_POINT_INFO(pDeoptimize) 2151d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung QUICK_ENTRY_POINT_INFO(pA64Load) 2152d9cb8ae2ed78f957a773af61759432d7a7bf78afDouglas Leung QUICK_ENTRY_POINT_INFO(pA64Store) 2153848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewEmptyString) 2154848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_B) 2155848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BI) 2156848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BII) 2157848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BIII) 2158848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BIIString) 2159848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BString) 2160848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BIICharset) 2161848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromBytes_BCharset) 2162848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromChars_C) 2163848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromChars_CII) 2164848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromChars_IIC) 2165848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromCodePoints) 2166848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromString) 2167848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromStringBuffer) 2168848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao QUICK_ENTRY_POINT_INFO(pNewStringFromStringBuilder) 21691cc71ebf333ca323ae0e130fefbce4593e385c10Hiroshi Yamauchi QUICK_ENTRY_POINT_INFO(pReadBarrierJni) 2170dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers#undef QUICK_ENTRY_POINT_INFO 2171dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 217298e2017cac7ca554602480fcefabbbe630a4a39bElliott Hughes os << offset; 217328fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes} 217428fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes 217594d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhaovoid Thread::QuickDeliverException() { 217662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Get exception from thread. 217714691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray mirror::Throwable* exception = GetException(); 21780aded089f565008ba5908e395e5914ca4f91f2deDave Allison CHECK(exception != nullptr); 217928ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers // Don't leave exception visible while we try to find the handler, which may cause class 2180d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes // resolution. 218128ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers ClearException(); 2182fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz bool is_deoptimization = (exception == GetDeoptimizationException()); 2183fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz QuickExceptionHandler exception_handler(this, is_deoptimization); 2184fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz if (is_deoptimization) { 2185fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz exception_handler.DeoptimizeStack(); 2186fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz } else { 218714691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray exception_handler.FindCatch(exception); 2188fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz } 2189fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz exception_handler.UpdateInstrumentationStack(); 2190fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz exception_handler.DoLongJump(); 2191bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 2192bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 2193bdb0391258abc54bf77c676e36847d28a783bfe5Ian RogersContext* Thread::GetLongJumpContext() { 2194dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Context* result = tlsPtr_.long_jump_context; 21950aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (result == nullptr) { 2196bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers result = Context::Create(); 21970399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } else { 2198dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.long_jump_context = nullptr; // Avoid context being shared. 21996702243ea2332b566d8e8b871cc9db0906d835adMathieu Chartier result->Reset(); 22001a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao } 2201bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers return result; 22021a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao} 22031a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 22044a8c3fa4bd8d95fac5671ab778dd00b6dc3ec0e4Andreas Gampe// Note: this visitor may return with a method set, but dex_pc_ being DexFile:kDexNoIndex. This is 22054a8c3fa4bd8d95fac5671ab778dd00b6dc3ec0e4Andreas Gampe// so we don't abort in a special situation (thinlocked monitor) when dumping the Java stack. 2206e0dcd46314d07eeb332edea292f5110178e4e3d2Ian Rogersstruct CurrentMethodVisitor FINAL : public StackVisitor { 22076ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe CurrentMethodVisitor(Thread* thread, Context* context, bool abort_on_error) 220862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 22098e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames), 22108e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray this_object_(nullptr), 22118e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray method_(nullptr), 22128e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray dex_pc_(0), 22136ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe abort_on_error_(abort_on_error) {} 2214e0dcd46314d07eeb332edea292f5110178e4e3d2Ian Rogers bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22153d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* m = GetMethod(); 221662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (m->IsRuntimeMethod()) { 221762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Continue if this is a runtime method. 221862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return true; 221962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 22200aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (context_ != nullptr) { 222162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers this_object_ = GetThisObject(); 22220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 222362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers method_ = m; 22246ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe dex_pc_ = GetDexPc(abort_on_error_); 222562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return false; 222662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 222762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Object* this_object_; 22283d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method_; 222962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t dex_pc_; 22306ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe const bool abort_on_error_; 223162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}; 22320399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 22333d21bdf8894e780d349c481e5c9e29fe1556051cMathieu ChartierArtMethod* Thread::GetCurrentMethod(uint32_t* dex_pc, bool abort_on_error) const { 22346ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe CurrentMethodVisitor visitor(const_cast<Thread*>(this), nullptr, abort_on_error); 22350399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers visitor.WalkStack(false); 22360aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (dex_pc != nullptr) { 22370399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers *dex_pc = visitor.dex_pc_; 2238d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes } 22390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers return visitor.method_; 2240ee0d3fb2fbd736484fe8c3177a4e965ea86d1c65TDYa} 224133dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao 2242dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersbool Thread::HoldsLock(mirror::Object* object) const { 22430aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (object == nullptr) { 22445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return false; 22455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2246dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return object->GetLockOwnerThreadId() == GetThreadId(); 22475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 22485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 224940e3bacfd57bca2ca39c1caec64680bd0ed4a16dIan Rogers// RootVisitor parameters are: (const Object* obj, size_t vreg, const StackVisitor* visitor). 225040e3bacfd57bca2ca39c1caec64680bd0ed4a16dIan Rogerstemplate <typename RootVisitor> 22510399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersclass ReferenceMapVisitor : public StackVisitor { 2252d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers public: 2253bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ReferenceMapVisitor(Thread* thread, Context* context, RootVisitor& visitor) 2254b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 22558e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray // We are visiting the references in compiled frames, so we do not need 22568e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray // to know the inlined frames. 22578e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread, context, StackVisitor::StackWalkKind::kSkipInlinedFrames), 22588e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray visitor_(visitor) {} 2259d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 2260b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22616a4be3a6226cec645cf905dd352e44f7968a7fa4Brian Carlstrom if (false) { 22620399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers LOG(INFO) << "Visiting stack roots in " << PrettyMethod(GetMethod()) 2263714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz << StringPrintf("@ PC:%04x", GetDexPc()); 22646a4be3a6226cec645cf905dd352e44f7968a7fa4Brian Carlstrom } 22650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ShadowFrame* shadow_frame = GetCurrentShadowFrame(); 22660aded089f565008ba5908e395e5914ca4f91f2deDave Allison if (shadow_frame != nullptr) { 2267714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz VisitShadowFrame(shadow_frame); 2268714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } else { 2269714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz VisitQuickFrame(); 2270714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2271714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz return true; 2272714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2273714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz 2274714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz void VisitShadowFrame(ShadowFrame* shadow_frame) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22753d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* m = shadow_frame->GetMethod(); 227692d1a666534aa98b173bb33dc5dba86b2d48aedbHiroshi Yamauchi DCHECK(m != nullptr); 2277714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz size_t num_regs = shadow_frame->NumberOfVRegs(); 2278714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz if (m->IsNative() || shadow_frame->HasReferenceArray()) { 2279eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // handle scope for JNI or References for interpreter. 2280714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz for (size_t reg = 0; reg < num_regs; ++reg) { 2281714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz mirror::Object* ref = shadow_frame->GetVRegReference(reg); 2282714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz if (ref != nullptr) { 2283714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz mirror::Object* new_ref = ref; 2284714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz visitor_(&new_ref, reg, this); 2285714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz if (new_ref != ref) { 2286714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz shadow_frame->SetVRegReference(reg, new_ref); 2287714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2288714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2289714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2290714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } else { 2291714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz // Java method. 2292714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz // Portable path use DexGcMap and store in Method.native_gc_map_. 2293957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier const uint8_t* gc_map = m->GetNativeGcMap(sizeof(void*)); 2294714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz CHECK(gc_map != nullptr) << PrettyMethod(m); 2295714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz verifier::DexPcToReferenceMap dex_gc_map(gc_map); 2296714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz uint32_t dex_pc = shadow_frame->GetDexPC(); 2297714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc); 2298714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz DCHECK(reg_bitmap != nullptr); 2299714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz num_regs = std::min(dex_gc_map.RegWidth() * 8, num_regs); 2300714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz for (size_t reg = 0; reg < num_regs; ++reg) { 2301714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz if (TestBitmap(reg, reg_bitmap)) { 23022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* ref = shadow_frame->GetVRegReference(reg); 2303423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier if (ref != nullptr) { 2304815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier mirror::Object* new_ref = ref; 2305815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier visitor_(&new_ref, reg, this); 2306423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier if (new_ref != ref) { 2307714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz shadow_frame->SetVRegReference(reg, new_ref); 2308423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier } 2309ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa } 2310ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa } 2311714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2312714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2313714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2314714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz 2315714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz private: 2316714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz void VisitQuickFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 23173d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* cur_quick_frame = GetCurrentQuickFrame(); 23183d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier DCHECK(cur_quick_frame != nullptr); 23193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* m = *cur_quick_frame; 2320cf4035a4c41ccfcc3e89a0cee25f5218a11b0705Andreas Gampe 2321714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz // Process register map (which native and runtime methods don't have) 2322714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz if (!m->IsNative() && !m->IsRuntimeMethod() && !m->IsProxyMethod()) { 2323a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier if (m->IsOptimized(sizeof(void*))) { 23243d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* vreg_base = reinterpret_cast<StackReference<mirror::Object>*>( 23253d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier reinterpret_cast<uintptr_t>(cur_quick_frame)); 23264c1c510bea6f20f4d8b09e15547cd2967ad51c88Vladimir Marko Runtime* runtime = Runtime::Current(); 2327a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*)); 23286f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point); 2329004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray CodeInfo code_info = m->GetOptimizedCodeInfo(); 2330004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset); 2331004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray MemoryRegion mask = map.GetStackMask(code_info); 2332988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray // Visit stack entries that hold pointers. 23333946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray for (size_t i = 0; i < mask.size_in_bits(); ++i) { 23343946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (mask.LoadBit(i)) { 23353d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier auto* ref_addr = vreg_base + i; 23363946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray mirror::Object* ref = ref_addr->AsMirrorPtr(); 23373946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (ref != nullptr) { 23383946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray mirror::Object* new_ref = ref; 23393946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray visitor_(&new_ref, -1, this); 23403946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (ref != new_ref) { 23413946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray ref_addr->Assign(new_ref); 2342423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier } 23433946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } 23443946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } 23453946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } 2346988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray // Visit callee-save registers that hold pointers. 2347004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray uint32_t register_mask = map.GetRegisterMask(code_info); 2348988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray for (size_t i = 0; i < BitSizeOf<uint32_t>(); ++i) { 2349988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray if (register_mask & (1 << i)) { 2350988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray mirror::Object** ref_addr = reinterpret_cast<mirror::Object**>(GetGPRAddress(i)); 2351988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray if (*ref_addr != nullptr) { 2352988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray visitor_(ref_addr, -1, this); 2353988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 2354988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 2355988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 23563946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } else { 2357957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier const uint8_t* native_gc_map = m->GetNativeGcMap(sizeof(void*)); 23583946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray CHECK(native_gc_map != nullptr) << PrettyMethod(m); 23593946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray const DexFile::CodeItem* code_item = m->GetCodeItem(); 23602cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Can't be null or how would we compile its instructions? 23613946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray DCHECK(code_item != nullptr) << PrettyMethod(m); 23623946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray NativePcOffsetToReferenceMap map(native_gc_map); 23633946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray size_t num_regs = std::min(map.RegWidth() * 8, 23643946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray static_cast<size_t>(code_item->registers_size_)); 23653946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (num_regs > 0) { 23663946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray Runtime* runtime = Runtime::Current(); 2367a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*)); 23686f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point); 23693946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray const uint8_t* reg_bitmap = map.FindBitMap(native_pc_offset); 23703946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray DCHECK(reg_bitmap != nullptr); 23713d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier const void* code_pointer = ArtMethod::EntryPointToCodePointer(entry_point); 2372a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier const VmapTable vmap_table(m->GetVmapTable(code_pointer, sizeof(void*))); 23733946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray QuickMethodFrameInfo frame_info = m->GetQuickFrameInfo(code_pointer); 23743946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray // For all dex registers in the bitmap 23753946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray DCHECK(cur_quick_frame != nullptr); 23763946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray for (size_t reg = 0; reg < num_regs; ++reg) { 23773946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray // Does this register hold a reference? 23783946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (TestBitmap(reg, reg_bitmap)) { 23793946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray uint32_t vmap_offset; 23803946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (vmap_table.IsInContext(reg, kReferenceVReg, &vmap_offset)) { 23813946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray int vmap_reg = vmap_table.ComputeRegister(frame_info.CoreSpillMask(), vmap_offset, 23823946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray kReferenceVReg); 23833946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray // This is sound as spilled GPRs will be word sized (ie 32 or 64bit). 23843946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray mirror::Object** ref_addr = 23853946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray reinterpret_cast<mirror::Object**>(GetGPRAddress(vmap_reg)); 23863946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (*ref_addr != nullptr) { 23873946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray visitor_(ref_addr, reg, this); 23883946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } 23893946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } else { 23903946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray StackReference<mirror::Object>* ref_addr = 239115b9d5274399736ac09705f0507df24fac4f00c1Nicolas Geoffray reinterpret_cast<StackReference<mirror::Object>*>(GetVRegAddrFromQuickCode( 239215b9d5274399736ac09705f0507df24fac4f00c1Nicolas Geoffray cur_quick_frame, code_item, frame_info.CoreSpillMask(), 239315b9d5274399736ac09705f0507df24fac4f00c1Nicolas Geoffray frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), reg)); 23943946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray mirror::Object* ref = ref_addr->AsMirrorPtr(); 23953946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (ref != nullptr) { 23963946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray mirror::Object* new_ref = ref; 23973946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray visitor_(&new_ref, reg, this); 23983946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray if (ref != new_ref) { 23993946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray ref_addr->Assign(new_ref); 24003946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray } 2401423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier } 24020399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers } 2403d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 24044f894e385e8ac018f078be75fea0a45696626b15Shih-wei Liao } 2405d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 2406d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 2407d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 2408d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers } 2409d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 24106f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier // Visitor for when we visit a root. 2411bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootVisitor& visitor_; 2412d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers}; 2413d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers 24146f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartierclass RootCallbackVisitor { 24156f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier public: 2416bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootCallbackVisitor(RootVisitor* visitor, uint32_t tid) : visitor_(visitor), tid_(tid) {} 24176f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier 2418bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void operator()(mirror::Object** obj, size_t vreg, const StackVisitor* stack_visitor) const 2419bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2420bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor_->VisitRoot(obj, JavaFrameRootInfo(tid_, stack_visitor, vreg)); 24216f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier } 24226f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier 24236f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier private: 2424bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootVisitor* const visitor_; 242583c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier const uint32_t tid_; 24266f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier}; 24276f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier 2428bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Thread::VisitRoots(RootVisitor* visitor) { 2429bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier const uint32_t thread_id = GetThreadId(); 2430bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRootIfNonNull(&tlsPtr_.opeer, RootInfo(kRootThreadObject, thread_id)); 2431fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz if (tlsPtr_.exception != nullptr && tlsPtr_.exception != GetDeoptimizationException()) { 2432bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRoot(reinterpret_cast<mirror::Object**>(&tlsPtr_.exception), 2433bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootInfo(kRootNativeStack, thread_id)); 243443d8bb870fadd4775a8513a1df955cdf66ad4b92Mathieu Chartier } 2435bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRootIfNonNull(&tlsPtr_.monitor_enter_object, RootInfo(kRootNativeStack, thread_id)); 2436bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier tlsPtr_.jni_env->locals.VisitRoots(visitor, RootInfo(kRootJNILocal, thread_id)); 2437bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier tlsPtr_.jni_env->monitors.VisitRoots(visitor, RootInfo(kRootJNIMonitor, thread_id)); 2438bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier HandleScopeVisitRoots(visitor, thread_id); 2439dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tlsPtr_.debug_invoke_req != nullptr) { 2440bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier tlsPtr_.debug_invoke_req->VisitRoots(visitor, RootInfo(kRootDebugger, thread_id)); 24413b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier } 2442ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang if (tlsPtr_.stacked_shadow_frame_record != nullptr) { 2443bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootCallbackVisitor visitor_to_callback(visitor, thread_id); 2444bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ReferenceMapVisitor<RootCallbackVisitor> mapper(this, nullptr, visitor_to_callback); 2445ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang for (StackedShadowFrameRecord* record = tlsPtr_.stacked_shadow_frame_record; 2446ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang record != nullptr; 2447ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang record = record->GetLink()) { 2448ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang for (ShadowFrame* shadow_frame = record->GetShadowFrame(); 2449ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang shadow_frame != nullptr; 2450ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang shadow_frame = shadow_frame->GetLink()) { 2451ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang mapper.VisitShadowFrame(shadow_frame); 2452ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang } 2453714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2454714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz } 2455ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang if (tlsPtr_.deoptimization_return_value_stack != nullptr) { 2456ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang for (DeoptimizationReturnValueRecord* record = tlsPtr_.deoptimization_return_value_stack; 2457ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang record != nullptr; 2458ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang record = record->GetLink()) { 2459ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang if (record->IsReference()) { 2460ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang visitor->VisitRootIfNonNull(record->GetGCRoot(), 2461ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang RootInfo(kRootThreadObject, thread_id)); 2462ef484d442a3dcae2cd1842c5be0623f5cf71e4abMingyao Yang } 24632a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe } 24642a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe } 2465d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier for (auto* verifier = tlsPtr_.method_verifier; verifier != nullptr; verifier = verifier->link_) { 2466d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier verifier->VisitRoots(visitor, RootInfo(kRootNativeStack, thread_id)); 246712d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier } 2468d6b1f6190c8ec42facb08aca34b093244774b318Ian Rogers // Visit roots on this thread's stack 24690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Context* context = GetLongJumpContext(); 2470bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootCallbackVisitor visitor_to_callback(visitor, thread_id); 2471e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context, visitor_to_callback); 24720399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers mapper.WalkStack(); 24730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ReleaseLongJumpContext(context); 2474423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier for (instrumentation::InstrumentationStackFrame& frame : *GetInstrumentationStack()) { 2475bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier visitor->VisitRootIfNonNull(&frame.this_object_, RootInfo(kRootVMInternal, thread_id)); 247662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 2477410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes} 2478410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 2479bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass VerifyRootVisitor : public SingleRootVisitor { 2480bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 2481bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::Object* root, const RootInfo& info ATTRIBUTE_UNUSED) 2482bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2483bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VerifyObject(root); 2484bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 2485bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 2486250455229aa0cc07bbd18174efe510bd52631a99jeffhao 248704d7aa92bc5548bc4d272b9480614f06248194ccIan Rogersvoid Thread::VerifyStackImpl() { 2488bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier VerifyRootVisitor visitor; 2489700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<Context> context(Context::Create()); 2490bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier RootCallbackVisitor visitor_to_callback(&visitor, GetThreadId()); 2491bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ReferenceMapVisitor<RootCallbackVisitor> mapper(this, context.get(), visitor_to_callback); 24920399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers mapper.WalkStack(); 2493250455229aa0cc07bbd18174efe510bd52631a99jeffhao} 2494250455229aa0cc07bbd18174efe510bd52631a99jeffhao 249500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// Set the stack end to that to be used during a stack overflow 249600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid Thread::SetStackEndForStackOverflow() { 24977571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom // During stack overflow we allow use of the full stack. 2498dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers if (tlsPtr_.stack_end == tlsPtr_.stack_begin) { 24997571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom // However, we seem to have already extended to use the full stack. 25007571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom LOG(ERROR) << "Need to increase kStackOverflowReservedBytes (currently " 25017ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe << GetStackOverflowReservedBytes(kRuntimeISA) << ")?"; 25027571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom DumpStack(LOG(ERROR)); 25037571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom LOG(FATAL) << "Recursive stack overflow."; 250400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 250500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 2506dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.stack_end = tlsPtr_.stack_begin; 2507648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 2508648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // Remove the stack overflow protection if is it set up. 2509648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison bool implicit_stack_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 2510648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (implicit_stack_check) { 2511648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (!UnprotectStack()) { 2512648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison LOG(ERROR) << "Unable to remove stack protection for stack overflow"; 2513648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 2514648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 251500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 251600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 251713735955f39b3b304c37d2b2840663c131262c18Ian Rogersvoid Thread::SetTlab(uint8_t* start, uint8_t* end) { 2518692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier DCHECK_LE(start, end); 2519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.thread_local_start = start; 2520dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.thread_local_pos = tlsPtr_.thread_local_start; 2521dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.thread_local_end = end; 2522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers tlsPtr_.thread_local_objects = 0; 2523692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier} 2524692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier 2525c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchibool Thread::HasTlab() const { 2526dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers bool has_tlab = tlsPtr_.thread_local_pos != nullptr; 2527c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi if (has_tlab) { 2528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DCHECK(tlsPtr_.thread_local_start != nullptr && tlsPtr_.thread_local_end != nullptr); 2529c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi } else { 2530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers DCHECK(tlsPtr_.thread_local_start == nullptr && tlsPtr_.thread_local_end == nullptr); 2531c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi } 2532c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi return has_tlab; 2533c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi} 2534c93c530efc175954160c3834c93961a1a946a35aHiroshi Yamauchi 2535330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Thread& thread) { 253600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers thread.ShortDump(os); 2537330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes return os; 2538330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes} 2539330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes 2540648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allisonvoid Thread::ProtectStack() { 2541648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison void* pregion = tlsPtr_.stack_begin - kStackOverflowProtectedSize; 2542648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison VLOG(threads) << "Protecting stack at " << pregion; 2543648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (mprotect(pregion, kStackOverflowProtectedSize, PROT_NONE) == -1) { 2544648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison LOG(FATAL) << "Unable to create protected region in stack for implicit overflow check. " 2545648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison "Reason: " 2546648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison << strerror(errno) << " size: " << kStackOverflowProtectedSize; 2547648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 2548648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison} 2549648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 2550648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allisonbool Thread::UnprotectStack() { 2551648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison void* pregion = tlsPtr_.stack_begin - kStackOverflowProtectedSize; 2552648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison VLOG(threads) << "Unprotecting stack at " << pregion; 2553648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return mprotect(pregion, kStackOverflowProtectedSize, PROT_READ|PROT_WRITE) == 0; 2554648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison} 2555648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 2556597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertzvoid Thread::ActivateSingleStepControl(SingleStepControl* ssc) { 2557597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz CHECK(Dbg::IsDebuggerActive()); 2558597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz CHECK(GetSingleStepControl() == nullptr) << "Single step already active in thread " << *this; 2559597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz CHECK(ssc != nullptr); 2560597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz tlsPtr_.single_step_control = ssc; 2561597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz} 2562597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz 2563597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertzvoid Thread::DeactivateSingleStepControl() { 2564597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz CHECK(Dbg::IsDebuggerActive()); 2565597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz CHECK(GetSingleStepControl() != nullptr) << "Single step not active in thread " << *this; 2566597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz SingleStepControl* ssc = GetSingleStepControl(); 2567597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz tlsPtr_.single_step_control = nullptr; 2568597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz delete ssc; 2569597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz} 2570648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 25711558b577907b613864e98f05862543557263e864Sebastien Hertzvoid Thread::SetDebugInvokeReq(DebugInvokeReq* req) { 25721558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(Dbg::IsDebuggerActive()); 25731558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(GetInvokeReq() == nullptr) << "Debug invoke req already active in thread " << *this; 25741558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(Thread::Current() != this) << "Debug invoke can't be dispatched by the thread itself"; 25751558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(req != nullptr); 25761558b577907b613864e98f05862543557263e864Sebastien Hertz tlsPtr_.debug_invoke_req = req; 25771558b577907b613864e98f05862543557263e864Sebastien Hertz} 25781558b577907b613864e98f05862543557263e864Sebastien Hertz 25791558b577907b613864e98f05862543557263e864Sebastien Hertzvoid Thread::ClearDebugInvokeReq() { 25801558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(GetInvokeReq() != nullptr) << "Debug invoke req not active in thread " << *this; 25811558b577907b613864e98f05862543557263e864Sebastien Hertz CHECK(Thread::Current() == this) << "Debug invoke must be finished by the thread itself"; 25826ba35b50347aa7418c66c7b046cd164987e95df3Sebastien Hertz DebugInvokeReq* req = tlsPtr_.debug_invoke_req; 25831558b577907b613864e98f05862543557263e864Sebastien Hertz tlsPtr_.debug_invoke_req = nullptr; 25846ba35b50347aa7418c66c7b046cd164987e95df3Sebastien Hertz delete req; 25851558b577907b613864e98f05862543557263e864Sebastien Hertz} 25861558b577907b613864e98f05862543557263e864Sebastien Hertz 2587d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartiervoid Thread::PushVerifier(verifier::MethodVerifier* verifier) { 2588d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier verifier->link_ = tlsPtr_.method_verifier; 258912d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier tlsPtr_.method_verifier = verifier; 259012d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier} 259112d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier 2592d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartiervoid Thread::PopVerifier(verifier::MethodVerifier* verifier) { 259312d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier CHECK_EQ(tlsPtr_.method_verifier, verifier); 2594d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier tlsPtr_.method_verifier = verifier->link_; 259512d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier} 259612d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier 25978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes} // namespace art 2598