Revert "Revert "ART: Use bionic TLS slot for thread-self""

This reverts commit 50832b6804d15ea5ddfe99a2753a09111b5bfe37.

Fix clearing the TLS on detach.

Change-Id: I75ed5ccccb4f31800e5f893055e96067a9695258
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 05cfc42..3a1bd09 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -209,6 +209,11 @@
   external/vixl/src \
   external/zlib \
 
+# We optimize Thread::Current() with a direct TLS access. This requires access to a private
+# Bionic header.
+# Note: technically we only need this on device, but this avoids the duplication of the includes.
+ART_C_INCLUDES += bionic/libc/private
+
 # Base set of cflags used by all things ART.
 art_cflags := \
   -fno-rtti \
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index 39ef68a..8bf241b 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -19,6 +19,10 @@
 
 #include "thread.h"
 
+#ifdef __ANDROID__
+#include <bionic_tls.h>  // Access to our own TLS slot.
+#endif
+
 #include <pthread.h>
 
 #include "base/casts.h"
@@ -41,7 +45,11 @@
   if (!is_started_) {
     return nullptr;
   } else {
+#ifdef __ANDROID__
+    void* thread = __get_tls()[TLS_SLOT_ART_THREAD_SELF];
+#else
     void* thread = pthread_getspecific(Thread::pthread_key_self_);
+#endif
     return reinterpret_cast<Thread*>(thread);
   }
 }
diff --git a/runtime/thread.cc b/runtime/thread.cc
index b3efad0..ba1121fb 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -527,7 +527,11 @@
   InitCardTable();
   InitTid();
 
+#ifdef __ANDROID__
+  __get_tls()[TLS_SLOT_ART_THREAD_SELF] = this;
+#else
   CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach self");
+#endif
   DCHECK_EQ(Thread::Current(), this);
 
   tls32_.thin_lock_thread_id = thread_list->AllocThreadId(this);
@@ -1349,7 +1353,11 @@
     LOG(WARNING) << "Native thread exiting without having called DetachCurrentThread (maybe it's "
         "going to use a pthread_key_create destructor?): " << *self;
     CHECK(is_started_);
+#ifdef __ANDROID__
+    __get_tls()[TLS_SLOT_ART_THREAD_SELF] = self;
+#else
     CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, self), "reattach self");
+#endif
     self->tls32_.thread_exit_check_count = 1;
   } else {
     LOG(FATAL) << "Native thread exited without calling DetachCurrentThread: " << *self;
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 60c9b5e..62d1e84 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -1228,7 +1228,11 @@
 
   // Clear the TLS data, so that the underlying native thread is recognizably detached.
   // (It may wish to reattach later.)
+#ifdef __ANDROID__
+  __get_tls()[TLS_SLOT_ART_THREAD_SELF] = nullptr;
+#else
   CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, nullptr), "detach self");
+#endif
 
   // Signal that a thread just detached.
   MutexLock mu(nullptr, *Locks::thread_list_lock_);