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