8132510: Replace ThreadLocalStorage with compiler/language-based thread-local variables
authordholmes
Fri, 04 Dec 2015 04:06:37 -0500
changeset 34633 2a6c7c7b30a7
parent 34632 bf3518bba285
child 34634 5b74061eb1bb
child 34635 2dab71a66523
child 34637 9b9298044d23
child 34639 cb73d3c05599
8132510: Replace ThreadLocalStorage with compiler/language-based thread-local variables Summary: Used compiled-based TLS when available. Additional contributions by Thomas Stufe (AIX) and Andrew Haley (Aarch64) Reviewed-by: stuefe, bdelsart, dcubed
hotspot/make/aix/makefiles/xlc.make
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/os/aix/vm/os_aix.cpp
hotspot/src/os/aix/vm/os_aix.inline.hpp
hotspot/src/os/aix/vm/thread_aix.inline.hpp
hotspot/src/os/bsd/vm/os_bsd.cpp
hotspot/src/os/bsd/vm/os_bsd.inline.hpp
hotspot/src/os/bsd/vm/thread_bsd.inline.hpp
hotspot/src/os/linux/vm/os_linux.cpp
hotspot/src/os/linux/vm/os_linux.inline.hpp
hotspot/src/os/linux/vm/thread_linux.inline.hpp
hotspot/src/os/posix/vm/threadLocalStorage_posix.cpp
hotspot/src/os/solaris/vm/os_solaris.cpp
hotspot/src/os/solaris/vm/thread_solaris.inline.hpp
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/src/os/windows/vm/os_windows.hpp
hotspot/src/os/windows/vm/threadLocalStorage_windows.cpp
hotspot/src/os/windows/vm/thread_windows.inline.hpp
hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp
hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.cpp
hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp
hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp
hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp
hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp
hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp
hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp
hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp
hotspot/src/os_cpu/linux_aarch64/vm/assembler_linux_aarch64.cpp
hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp
hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.cpp
hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.hpp
hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.s
hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp
hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp
hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp
hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
hotspot/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp
hotspot/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.hpp
hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp
hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
hotspot/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp
hotspot/src/os_cpu/linux_x86/vm/threadLS_linux_x86.hpp
hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp
hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp
hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp
hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp
hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp
hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp
hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp
hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp
hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp
hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
hotspot/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
hotspot/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp
hotspot/src/share/vm/code/nmethod.cpp
hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp
hotspot/src/share/vm/gc/g1/g1HotCardCache.hpp
hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp
hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp
hotspot/src/share/vm/gc/shared/workgroup.cpp
hotspot/src/share/vm/memory/allocation.cpp
hotspot/src/share/vm/memory/resourceArea.hpp
hotspot/src/share/vm/oops/oopsHierarchy.cpp
hotspot/src/share/vm/precompiled/precompiled.hpp
hotspot/src/share/vm/prims/jni.cpp
hotspot/src/share/vm/prims/jniCheck.cpp
hotspot/src/share/vm/prims/jvmtiEnter.xsl
hotspot/src/share/vm/prims/jvmtiExport.cpp
hotspot/src/share/vm/prims/jvmtiUtil.hpp
hotspot/src/share/vm/runtime/interfaceSupport.cpp
hotspot/src/share/vm/runtime/interfaceSupport.hpp
hotspot/src/share/vm/runtime/java.cpp
hotspot/src/share/vm/runtime/mutex.cpp
hotspot/src/share/vm/runtime/mutexLocker.cpp
hotspot/src/share/vm/runtime/os.cpp
hotspot/src/share/vm/runtime/os.hpp
hotspot/src/share/vm/runtime/sharedRuntime.hpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
hotspot/src/share/vm/runtime/thread.inline.hpp
hotspot/src/share/vm/runtime/threadLocalStorage.cpp
hotspot/src/share/vm/runtime/threadLocalStorage.hpp
hotspot/src/share/vm/runtime/vmThread.cpp
hotspot/src/share/vm/runtime/vm_operations.cpp
hotspot/src/share/vm/utilities/debug.cpp
hotspot/src/share/vm/utilities/events.cpp
hotspot/src/share/vm/utilities/events.hpp
hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp
hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp
hotspot/src/share/vm/utilities/ostream.cpp
--- a/hotspot/make/aix/makefiles/xlc.make	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/make/aix/makefiles/xlc.make	Fri Dec 04 04:06:37 2015 -0500
@@ -74,6 +74,9 @@
 CFLAGS += -qnortti
 CFLAGS += -qnoeh
 
+# for compiler-level tls
+CFLAGS += -qtls=default
+
 CFLAGS += -D_REENTRANT
 # no xlc counterpart for -fcheck-new
 # CFLAGS += -fcheck-new
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -41,6 +41,7 @@
 #include "runtime/icache.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
 
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1CollectedHeap.inline.hpp"
@@ -4653,3 +4654,23 @@
     BIND(DONE);
       sub(result, result, len); // Return index where we stopped
 }
+
+// get_thread() can be called anywhere inside generated code so we
+// need to save whatever non-callee save context might get clobbered
+// by the call to JavaThread::aarch64_get_thread_helper() or, indeed,
+// the call setup code.
+//
+// aarch64_get_thread_helper() clobbers only r0, r1, and flags.
+//
+void MacroAssembler::get_thread(Register dst) {
+  RegSet saved_regs = RegSet::range(r0, r1) + lr - dst;
+  push(saved_regs, sp);
+
+  mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper));
+  blrt(lr, 1, 0, 1);
+  if (dst != c_rarg0) {
+    mov(dst, c_rarg0);
+  }
+
+  pop(saved_regs, sp);
+}
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -360,10 +360,10 @@
 #ifdef ASSERT
 // a hook for debugging
 static Thread* reinitialize_thread() {
-  return ThreadLocalStorage::thread();
+  return Thread::current();
 }
 #else
-#define reinitialize_thread ThreadLocalStorage::thread
+#define reinitialize_thread Thread::current
 #endif
 
 #ifdef ASSERT
@@ -393,7 +393,7 @@
 }
 
 static Thread* verify_thread_subroutine(Thread* gthread_value) {
-  Thread* correct_value = ThreadLocalStorage::thread();
+  Thread* correct_value = Thread::current();
   guarantee(gthread_value == correct_value, "G2_thread value must be the thread");
   return correct_value;
 }
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -36,7 +36,7 @@
   address _flush_reg_windows();   // in .s file.
   // Flush registers to stack. In case of error we will need to stack walk.
   address bootstrap_flush_windows(void) {
-    Thread* thread = ThreadLocalStorage::get_thread_slow();
+    Thread* thread = Thread::current_or_null();
     // Very early in process there is no thread.
     if (thread != NULL) {
       guarantee(thread->is_Java_thread(), "Not a Java thread.");
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -39,6 +39,7 @@
 #include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
+#include "runtime/thread.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1CollectedHeap.inline.hpp"
@@ -10834,3 +10835,43 @@
 SkipIfEqual::~SkipIfEqual() {
   _masm->bind(_label);
 }
+
+// 32-bit Windows has its own fast-path implementation
+// of get_thread
+#if !defined(WIN32) || defined(_LP64)
+
+// This is simply a call to Thread::current()
+void MacroAssembler::get_thread(Register thread) {
+  if (thread != rax) {
+    push(rax);
+  }
+  LP64_ONLY(push(rdi);)
+  LP64_ONLY(push(rsi);)
+  push(rdx);
+  push(rcx);
+#ifdef _LP64
+  push(r8);
+  push(r9);
+  push(r10);
+  push(r11);
+#endif
+
+  MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, Thread::current), 0);
+
+#ifdef _LP64
+  pop(r11);
+  pop(r10);
+  pop(r9);
+  pop(r8);
+#endif
+  pop(rcx);
+  pop(rdx);
+  LP64_ONLY(pop(rsi);)
+  LP64_ONLY(pop(rdi);)
+  if (thread != rax) {
+    mov(thread, rax);
+    pop(rax);
+  }
+}
+
+#endif
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -902,7 +902,7 @@
   int pid = os::current_process_id();
   alloca(((pid ^ counter++) & 7) * 128);
 
-  ThreadLocalStorage::set_thread(thread);
+  thread->initialize_thread_current();
 
   OSThread* osthread = thread->osthread();
 
@@ -1077,32 +1077,6 @@
   delete osthread;
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// thread local storage
-
-int os::allocate_thread_local_storage() {
-  pthread_key_t key;
-  int rslt = pthread_key_create(&key, NULL);
-  assert(rslt == 0, "cannot allocate thread local storage");
-  return (int)key;
-}
-
-// Note: This is currently not used by VM, as we don't destroy TLS key
-// on VM exit.
-void os::free_thread_local_storage(int index) {
-  int rslt = pthread_key_delete((pthread_key_t)index);
-  assert(rslt == 0, "invalid index");
-}
-
-void os::thread_local_storage_at_put(int index, void* value) {
-  int rslt = pthread_setspecific((pthread_key_t)index, value);
-  assert(rslt == 0, "pthread_setspecific failed");
-}
-
-extern "C" Thread* get_thread() {
-  return ThreadLocalStorage::thread();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // time support
 
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -36,10 +36,6 @@
 #include <sys/ioctl.h>
 #include <netdb.h>
 
-inline void* os::thread_local_storage_at(int index) {
-  return pthread_getspecific((pthread_key_t)index);
-}
-
 // File names are case-sensitive on windows only.
 inline int os::file_name_strcmp(const char* s1, const char* s2) {
   return strcmp(s1, s2);
--- a/hotspot/src/os/aix/vm/thread_aix.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_AIX_VM_THREAD_AIX_INLINE_HPP
-#define OS_AIX_VM_THREAD_AIX_INLINE_HPP
-
-#include "runtime/thread.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Contains inlined functions for class Thread and ThreadLocalStorage
-
-inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
-
-#endif // OS_AIX_VM_THREAD_AIX_INLINE_HPP
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -674,7 +674,7 @@
   int pid = os::current_process_id();
   alloca(((pid ^ counter++) & 7) * 128);
 
-  ThreadLocalStorage::set_thread(thread);
+  thread->initialize_thread_current();
 
   OSThread* osthread = thread->osthread();
   Monitor* sync = osthread->startThread_lock();
@@ -882,44 +882,6 @@
   delete osthread;
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// thread local storage
-
-// Restore the thread pointer if the destructor is called. This is in case
-// someone from JNI code sets up a destructor with pthread_key_create to run
-// detachCurrentThread on thread death. Unless we restore the thread pointer we
-// will hang or crash. When detachCurrentThread is called the key will be set
-// to null and we will not be called again. If detachCurrentThread is never
-// called we could loop forever depending on the pthread implementation.
-static void restore_thread_pointer(void* p) {
-  Thread* thread = (Thread*) p;
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
-
-int os::allocate_thread_local_storage() {
-  pthread_key_t key;
-  int rslt = pthread_key_create(&key, restore_thread_pointer);
-  assert(rslt == 0, "cannot allocate thread local storage");
-  return (int)key;
-}
-
-// Note: This is currently not used by VM, as we don't destroy TLS key
-// on VM exit.
-void os::free_thread_local_storage(int index) {
-  int rslt = pthread_key_delete((pthread_key_t)index);
-  assert(rslt == 0, "invalid index");
-}
-
-void os::thread_local_storage_at_put(int index, void* value) {
-  int rslt = pthread_setspecific((pthread_key_t)index, value);
-  assert(rslt == 0, "pthread_setspecific failed");
-}
-
-extern "C" Thread* get_thread() {
-  return ThreadLocalStorage::thread();
-}
-
-
 ////////////////////////////////////////////////////////////////////////////////
 // time support
 
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,6 @@
 #include <sys/poll.h>
 #include <netdb.h>
 
-inline void* os::thread_local_storage_at(int index) {
-  return pthread_getspecific((pthread_key_t)index);
-}
-
 // File names are case-sensitive on windows only
 inline int os::file_name_strcmp(const char* s1, const char* s2) {
   return strcmp(s1, s2);
--- a/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_BSD_VM_THREAD_BSD_INLINE_HPP
-#define OS_BSD_VM_THREAD_BSD_INLINE_HPP
-
-#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
-#error "This file should only be included from thread.inline.hpp"
-#endif
-
-#include "runtime/thread.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Contains inlined functions for class Thread and ThreadLocalStorage
-
-inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
-
-#endif // OS_BSD_VM_THREAD_BSD_INLINE_HPP
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -646,7 +646,7 @@
   int pid = os::current_process_id();
   alloca(((pid ^ counter++) & 7) * 128);
 
-  ThreadLocalStorage::set_thread(thread);
+  thread->initialize_thread_current();
 
   OSThread* osthread = thread->osthread();
   Monitor* sync = osthread->startThread_lock();
@@ -874,43 +874,6 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-// thread local storage
-
-// Restore the thread pointer if the destructor is called. This is in case
-// someone from JNI code sets up a destructor with pthread_key_create to run
-// detachCurrentThread on thread death. Unless we restore the thread pointer we
-// will hang or crash. When detachCurrentThread is called the key will be set
-// to null and we will not be called again. If detachCurrentThread is never
-// called we could loop forever depending on the pthread implementation.
-static void restore_thread_pointer(void* p) {
-  Thread* thread = (Thread*) p;
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
-
-int os::allocate_thread_local_storage() {
-  pthread_key_t key;
-  int rslt = pthread_key_create(&key, restore_thread_pointer);
-  assert(rslt == 0, "cannot allocate thread local storage");
-  return (int)key;
-}
-
-// Note: This is currently not used by VM, as we don't destroy TLS key
-// on VM exit.
-void os::free_thread_local_storage(int index) {
-  int rslt = pthread_key_delete((pthread_key_t)index);
-  assert(rslt == 0, "invalid index");
-}
-
-void os::thread_local_storage_at_put(int index, void* value) {
-  int rslt = pthread_setspecific((pthread_key_t)index, value);
-  assert(rslt == 0, "pthread_setspecific failed");
-}
-
-extern "C" Thread* get_thread() {
-  return ThreadLocalStorage::thread();
-}
-
-//////////////////////////////////////////////////////////////////////////////
 // initial thread
 
 // Check if current thread is the initial thread, similar to Solaris thr_main.
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,6 @@
 #include <sys/poll.h>
 #include <netdb.h>
 
-inline void* os::thread_local_storage_at(int index) {
-  return pthread_getspecific((pthread_key_t)index);
-}
-
 // File names are case-sensitive on windows only
 inline int os::file_name_strcmp(const char* s1, const char* s2) {
   return strcmp(s1, s2);
--- a/hotspot/src/os/linux/vm/thread_linux.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
-#define OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
-
-#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
-#error "This file should only be included from thread.inline.hpp"
-#endif
-
-#include "runtime/thread.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Contains inlined functions for class Thread and ThreadLocalStorage
-
-inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
-
-#endif // OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/posix/vm/threadLocalStorage_posix.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "runtime/threadLocalStorage.hpp"
+#include <pthread.h>
+
+static pthread_key_t _thread_key;
+static bool _initialized = false;
+
+// Restore the thread pointer if the destructor is called. This is in case
+// someone from JNI code sets up a destructor with pthread_key_create to run
+// detachCurrentThread on thread death. Unless we restore the thread pointer we
+// will hang or crash. When detachCurrentThread is called the key will be set
+// to null and we will not be called again. If detachCurrentThread is never
+// called we could loop forever depending on the pthread implementation.
+extern "C" void restore_thread_pointer(void* p) {
+  ThreadLocalStorage::set_thread((Thread*) p);
+}
+
+void ThreadLocalStorage::init() {
+  assert(!_initialized, "initializing TLS more than once!");
+  int rslt = pthread_key_create(&_thread_key, restore_thread_pointer);
+  // If this assert fails we will get a recursive assertion failure
+  // and not see the actual error message or get a hs_err file
+  assert_status(rslt == 0, rslt, "pthread_key_create");
+  _initialized = true;
+}
+
+bool ThreadLocalStorage::is_initialized() {
+  return _initialized;
+}
+
+Thread* ThreadLocalStorage::thread() {
+  // If this assert fails we will get a recursive assertion failure
+  // and not see the actual error message or get a hs_err file.
+  // Which most likely indicates we have taken an error path early in
+  // the initialization process, which is using Thread::current without
+  // checking TLS is initialized - see java.cpp vm_exit
+  assert(_initialized, "TLS not initialized yet!");
+  return (Thread*) pthread_getspecific(_thread_key); // may be NULL
+}
+
+void ThreadLocalStorage::set_thread(Thread* current) {
+  assert(_initialized, "TLS not initialized yet!");
+  int rslt = pthread_setspecific(_thread_key, current);
+  assert_status(rslt == 0, rslt, "pthread_setspecific");
+}
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -728,6 +728,9 @@
 
   int prio;
   Thread* thread = (Thread*)thread_addr;
+
+  thread->initialize_thread_current();
+
   OSThread* osthr = thread->osthread();
 
   osthr->set_lwp_id(_lwp_self());  // Store lwp in case we are bound
@@ -5579,7 +5582,7 @@
 
   // fork is async-safe, fork1 is not so can't use in signal handler
   pid_t pid;
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
   if (t != NULL && t->is_inside_signal_handler()) {
     pid = fork();
   } else {
--- a/hotspot/src/os/solaris/vm/thread_solaris.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
-#define OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
-
-#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
-#error "This file should only be included from thread.inline.hpp"
-#endif
-
-#include "runtime/thread.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of
-// startup.
-// ThreadLocalStorage::thread is warm -- it's called > 16K times in the same
-// period.   Thread::current() now calls ThreadLocalStorage::thread() directly.
-// For SPARC, to avoid excessive register window spill-fill faults,
-// we aggressively inline these routines.
-
-inline void ThreadLocalStorage::set_thread(Thread* thread) {
-  _thr_current = thread;
-}
-
-inline Thread* ThreadLocalStorage::thread()  {
-  return _thr_current;
-}
-
-#endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -419,6 +419,8 @@
   int pid = os::current_process_id();
   _alloca(((pid ^ counter++) & 7) * 128);
 
+  thread->initialize_thread_current();
+
   OSThread* osthr = thread->osthread();
   assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
 
@@ -2146,7 +2148,7 @@
 
 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
                       address handler) {
-  JavaThread* thread = JavaThread::current();
+    JavaThread* thread = (JavaThread*) Thread::current_or_null();
   // Save pc in thread
 #ifdef _M_IA64
   // Do not blow up if no thread info available.
@@ -2384,7 +2386,7 @@
   address pc = (address) exceptionInfo->ContextRecord->Eip;
   #endif
 #endif
-  Thread* t = ThreadLocalStorage::get_thread_slow();          // slow & steady
+  Thread* t = Thread::current_or_null_safe();
 
   // Handle SafeFetch32 and SafeFetchN exceptions.
   if (StubRoutines::is_safefetch_fault(pc)) {
@@ -4011,27 +4013,6 @@
   return result == IDYES;
 }
 
-int os::allocate_thread_local_storage() {
-  return TlsAlloc();
-}
-
-
-void os::free_thread_local_storage(int index) {
-  TlsFree(index);
-}
-
-
-void os::thread_local_storage_at_put(int index, void* value) {
-  TlsSetValue(index, value);
-  assert(thread_local_storage_at(index) == value, "Just checking");
-}
-
-
-void* os::thread_local_storage_at(int index) {
-  return TlsGetValue(index);
-}
-
-
 #ifndef PRODUCT
 #ifndef _WIN64
 // Helpers to check whether NX protection is enabled
@@ -4079,6 +4060,9 @@
     fatal("DuplicateHandle failed\n");
   }
   main_thread_id = (int) GetCurrentThreadId();
+
+  // initialize fast thread access - only used for 32-bit
+  win32::initialize_thread_ptr_offset();
 }
 
 // To install functions for atexit processing
@@ -5177,9 +5161,7 @@
     }
   }
 
-  JavaThread* thread = (JavaThread*)(Thread::current());
-  assert(thread->is_Java_thread(), "Must be JavaThread");
-  JavaThread *jt = (JavaThread *)thread;
+  JavaThread* thread = JavaThread::current();
 
   // Don't wait if interrupted or already triggered
   if (Thread::is_interrupted(thread, false) ||
@@ -5187,16 +5169,16 @@
     ResetEvent(_ParkEvent);
     return;
   } else {
-    ThreadBlockInVM tbivm(jt);
+    ThreadBlockInVM tbivm(thread);
     OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
-    jt->set_suspend_equivalent();
+    thread->set_suspend_equivalent();
 
     WaitForSingleObject(_ParkEvent, time);
     ResetEvent(_ParkEvent);
 
     // If externally suspended while waiting, re-suspend
-    if (jt->handle_special_suspend_equivalent_condition()) {
-      jt->java_suspend_self();
+    if (thread->handle_special_suspend_equivalent_condition()) {
+      thread->java_suspend_self();
     }
   }
 }
@@ -5299,7 +5281,7 @@
   DWORD exception_code = e->ExceptionRecord->ExceptionCode;
 
   if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
-    JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
+    JavaThread* thread = JavaThread::current();
     PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
     address addr = (address) exceptionRecord->ExceptionInformation[1];
 
@@ -6066,3 +6048,15 @@
   return -1;
 }
 
+// Fast current thread access
+
+int os::win32::_thread_ptr_offset = 0;
+
+static void call_wrapper_dummy() {}
+
+// We need to call the os_exception_wrapper once so that it sets
+// up the offset from FS of the thread pointer.
+void os::win32::initialize_thread_ptr_offset() {
+  os::os_exception_wrapper((java_call_t)call_wrapper_dummy,
+                           NULL, NULL, NULL, NULL);
+}
--- a/hotspot/src/os/windows/vm/os_windows.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -117,6 +117,17 @@
 
   // filter function to ignore faults on serializations page
   static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
+
+  // Fast access to current thread
+protected:
+  static int _thread_ptr_offset;
+private:
+  static void initialize_thread_ptr_offset();
+public:
+  static inline void set_thread_ptr_offset(int offset) {
+    _thread_ptr_offset = offset;
+  }
+  static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
 };
 
 /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/threadLocalStorage_windows.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/threadLocalStorage.hpp"
+#include <windows.h>
+
+static DWORD _thread_key;
+static bool _initialized = false;
+
+
+void ThreadLocalStorage::init() {
+  assert(!_initialized, "initializing TLS more than once!");
+  _thread_key = TlsAlloc();
+  // If this assert fails we will get a recursive assertion failure
+  // and not see the actual error message or get a hs_err file
+  assert(_thread_key != TLS_OUT_OF_INDEXES, "TlsAlloc failed: out of indices");
+  _initialized = true;
+}
+
+bool ThreadLocalStorage::is_initialized() {
+  return _initialized;
+}
+
+Thread* ThreadLocalStorage::thread() {
+  // If this assert fails we will get a recursive assertion failure
+  // and not see the actual error message or get a hs_err file.
+  // Which most likely indicates we have taken an error path early in
+  // the initialization process, which is using Thread::current without
+  // checking TLS is initialized - see java.cpp vm_exit
+  assert(_initialized, "TLS not initialized yet!");
+  Thread* current = (Thread*) TlsGetValue(_thread_key);
+  assert(current != 0 || GetLastError() == ERROR_SUCCESS,
+         "TlsGetValue failed with error code: %lu", GetLastError());
+  return current;
+}
+
+void ThreadLocalStorage::set_thread(Thread* current) {
+  assert(_initialized, "TLS not initialized yet!");
+  BOOL res = TlsSetValue(_thread_key, current);
+  assert(res, "TlsSetValue failed with error code: %lu", GetLastError());
+}
--- a/hotspot/src/os/windows/vm/thread_windows.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
-#define OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
-
-#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
-#error "This file should only be included from thread.inline.hpp"
-#endif
-
-#include "runtime/thread.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Contains inlined functions for class Thread and ThreadLocalStorage
-
-inline void ThreadLocalStorage::pd_invalidate_all()            { return; }
-
-#endif // OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -167,7 +167,7 @@
 
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();   // slow & steady
+  Thread* t = Thread::current_or_null_safe();
 
   SignalHandlerMark shm(t);
 
--- a/hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/threadLocalStorage.hpp"
-#include "runtime/thread.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-  // Nothing we can do here for user-level thread.
-}
-
-void ThreadLocalStorage::pd_init() {
-  // Nothing to do.
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
-#define OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
-
-  // Processor dependent parts of ThreadLocalStorage
-
-public:
-  static Thread* thread() {
-    return (Thread *) os::thread_local_storage_at(thread_index());
-  }
-
-#endif // OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP
--- a/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,62 +26,7 @@
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
 
-#ifndef _LP64
-void MacroAssembler::int3() {
-  call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MacroAssembler::get_thread(Register thread) {
-  movl(thread, rsp);
-  shrl(thread, PAGE_SHIFT);
-
-  ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr());
-  Address index(noreg, thread, Address::times_4);
-  ArrayAddress tls(tls_base, index);
-
-  movptr(thread, tls);
-}
-#else
 void MacroAssembler::int3() {
   call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
 }
-
-void MacroAssembler::get_thread(Register thread) {
-  // call pthread_getspecific
-  // void * pthread_getspecific(pthread_key_t key);
-   if (thread != rax) {
-     push(rax);
-   }
-   push(rdi);
-   push(rsi);
-   push(rdx);
-   push(rcx);
-   push(r8);
-   push(r9);
-   push(r10);
-   // XXX
-   mov(r10, rsp);
-   andq(rsp, -16);
-   push(r10);
-   push(r11);
-
-   movl(rdi, ThreadLocalStorage::thread_index());
-   call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
-
-   pop(r11);
-   pop(rsp);
-   pop(r10);
-   pop(r9);
-   pop(r8);
-   pop(rcx);
-   pop(rdx);
-   pop(rsi);
-   pop(rdi);
-   if (thread != rax) {
-       mov(thread, rax);
-       pop(rax);
-   }
-}
-#endif
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -405,7 +405,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Map stack pointer (%esp) to thread pointer for faster TLS access
-//
-// Here we use a flat table for better performance. Getting current thread
-// is down to one memory access (read _sp_map[%esp>>12]) in generated code
-// and two in runtime code (-fPIC code needs an extra load for _sp_map).
-//
-// This code assumes stack page is not shared by different threads. It works
-// in 32-bit VM when page size is 4K (or a multiple of 4K, if that matters).
-//
-// Notice that _sp_map is allocated in the bss segment, which is ZFOD
-// (zero-fill-on-demand). While it reserves 4M address space upfront,
-// actual memory pages are committed on demand.
-//
-// If an application creates and destroys a lot of threads, usually the
-// stack space freed by a thread will soon get reused by new thread
-// (this is especially true in NPTL or BsdThreads in fixed-stack mode).
-// No memory page in _sp_map is wasted.
-//
-// However, it's still possible that we might end up populating &
-// committing a large fraction of the 4M table over time, but the actual
-// amount of live data in the table could be quite small. The max wastage
-// is less than 4M bytes. If it becomes an issue, we could use madvise()
-// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
-// MADV_DONTNEED on Bsd keeps the virtual memory mapping, but zaps the
-// physical memory page (i.e. similar to MADV_FREE on Solaris).
-
-#ifndef AMD64
-Thread* ThreadLocalStorage::_sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
-#endif // !AMD64
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    // nothing we can do here for user-level thread
-}
-
-void ThreadLocalStorage::pd_init() {
-#ifndef AMD64
-  assert(align_size_down(os::vm_page_size(), PAGE_SIZE) == os::vm_page_size(),
-         "page size must be multiple of PAGE_SIZE");
-#endif // !AMD64
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-
-#ifndef AMD64
-  address stack_top = os::current_stack_base();
-  size_t stack_size = os::current_stack_size();
-
-  for (address p = stack_top - stack_size; p < stack_top; p += PAGE_SIZE) {
-    // pd_set_thread() is called with non-NULL value when a new thread is
-    // created/attached, or with NULL value when a thread is about to exit.
-    // If both "thread" and the corresponding _sp_map[] entry are non-NULL,
-    // they should have the same value. Otherwise it might indicate that the
-    // stack page is shared by multiple threads. However, a more likely cause
-    // for this assertion to fail is that an attached thread exited without
-    // detaching itself from VM, which is a program error and could cause VM
-    // to crash.
-    assert(thread == NULL || _sp_map[(uintptr_t)p >> PAGE_SHIFT] == NULL ||
-           thread == _sp_map[(uintptr_t)p >> PAGE_SHIFT],
-           "thread exited without detaching from VM??");
-    _sp_map[(uintptr_t)p >> PAGE_SHIFT] = thread;
-  }
-#endif // !AMD64
-}
--- a/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
-#define OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
-
-  // Processor dependent parts of ThreadLocalStorage
-
-#ifndef AMD64
-  // map stack pointer to thread pointer - see notes in threadLS_bsd_x86.cpp
-  #define SP_BITLENGTH  32
-#ifndef PAGE_SHIFT
-  #define PAGE_SHIFT    12
-  #define PAGE_SIZE     (1UL << PAGE_SHIFT)
-#endif
-  static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
-#endif // !AMD64
-
-public:
-
-#ifndef AMD64
-  static Thread** sp_map_addr() { return _sp_map; }
-#endif // !AMD64
-
-  static Thread* thread() {
-#ifdef AMD64
-    return (Thread*) os::thread_local_storage_at(thread_index());
-#else
-    uintptr_t sp;
-    __asm__ volatile ("movl %%esp, %0" : "=r" (sp));
-    return _sp_map[sp >> PAGE_SHIFT];
-#endif // AMD64
-  }
-
-#endif // OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
--- a/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -23,10 +23,4 @@
  *
  */
 
-#include "precompiled.hpp"
-#include "asm/assembler.hpp"
-#include "assembler_zero.inline.hpp"
-#include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
 // This file is intentionally empty
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -134,7 +134,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   SignalHandlerMark shm(t);
 
--- a/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-  // nothing to do
-}
-
-void ThreadLocalStorage::pd_init() {
-  // nothing to do
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
-#define OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
-
-// Processor dependent parts of ThreadLocalStorage
-
- public:
-  static Thread* thread() {
-    return (Thread*) os::thread_local_storage_at(thread_index());
-  }
-
-#endif // OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
--- a/hotspot/src/os_cpu/linux_aarch64/vm/assembler_linux_aarch64.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/assembler_linux_aarch64.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -23,32 +23,6 @@
  *
  */
 
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
+// nothing required here
 
 
-// get_thread can be called anywhere inside generated code so we need
-// to save whatever non-callee save context might get clobbered by the
-// call to the C thread_local lookup call or, indeed, the call setup
-// code. x86 appears to save C arg registers.
-
-void MacroAssembler::get_thread(Register dst) {
-  // call pthread_getspecific
-  // void * pthread_getspecific(pthread_key_t key);
-
-  // Save all call-clobbered regs except dst, plus r19 and r20.
-  RegSet saved_regs = RegSet::range(r0, r20) + lr - dst;
-  push(saved_regs, sp);
-  mov(c_rarg0, ThreadLocalStorage::thread_index());
-  mov(r19, CAST_FROM_FN_PTR(address, pthread_getspecific));
-  blrt(r19, 1, 0, 1);
-  if (dst != c_rarg0) {
-    mov(dst, c_rarg0);
-  }
-  // restore pushed registers
-  pop(saved_regs, sp);
-}
-
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -249,7 +249,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/threadLocalStorage.hpp"
-#include "runtime/thread.inline.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    // nothing we can do here for user-level thread
-}
-
-void ThreadLocalStorage::pd_init() {
-}
-
-__thread Thread *aarch64_currentThread;
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-  aarch64_currentThread = thread;
-}
--- a/hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
-#define OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
-
-  // Processor dependent parts of ThreadLocalStorage
-
-public:
-
-  static Thread *thread() {
-    return aarch64_currentThread;
-  }
-
-#endif // OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.s	Fri Dec 04 04:06:37 2015 -0500
@@ -0,0 +1,44 @@
+// Copyright (c) 2015, Red Hat Inc. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+
+        // JavaThread::aarch64_get_thread_helper()
+        //
+        // Return the current thread pointer in x0.
+        // Clobber x1, flags.
+        // All other registers are preserved,
+
+	.global	_ZN10JavaThread25aarch64_get_thread_helperEv
+	.type	_ZN10JavaThread25aarch64_get_thread_helperEv, %function
+
+_ZN10JavaThread25aarch64_get_thread_helperEv:
+	stp x29, x30, [sp, -16]!
+	adrp x0, :tlsdesc:_ZN6Thread12_thr_currentE
+	ldr x1, [x0, #:tlsdesc_lo12:_ZN6Thread12_thr_currentE]
+	add x0, x0, :tlsdesc_lo12:_ZN6Thread12_thr_currentE
+	.tlsdesccall _ZN6Thread12_thr_currentE
+	blr x1
+	mrs x1, tpidr_el0
+	add x0, x1, x0
+	ldr x0, [x0]
+	ldp x29, x30, [sp], 16
+	ret
+
+	.size _ZN10JavaThread25aarch64_get_thread_helperEv, .-_ZN10JavaThread25aarch64_get_thread_helperEv
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -77,6 +77,8 @@
   bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
 public:
 
+  static Thread *aarch64_get_thread_helper();
+
   // These routines are only used on cpu architectures that
   // have separate register stacks (Itanium).
   static bool register_stack_overflow() { return false; }
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -182,7 +182,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   SignalHandlerMark shm(t);
 
--- a/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    // nothing we can do here for user-level thread
-}
-
-void ThreadLocalStorage::pd_init() {
-  // Nothing to do
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_LINUX_PPC_VM_THREADLS_LINUX_PPC_HPP
-#define OS_CPU_LINUX_PPC_VM_THREADLS_LINUX_PPC_HPP
-
-  // Processor dependent parts of ThreadLocalStorage
-
-public:
-  static Thread* thread() {
-    return (Thread *) os::thread_local_storage_at(thread_index());
-  }
-
-#endif // OS_CPU_LINUX_PPC_VM_THREADLS_LINUX_PPC_HPP
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -541,7 +541,7 @@
   ucontext_t* ucFake = (ucontext_t*) ucVoid;
   sigcontext* uc = (sigcontext*)ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-}
-
-void ThreadLocalStorage::pd_init() {
-   // Nothing to do
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_LINUX_SPARC_VM_THREADLS_LINUX_SPARC_HPP
-#define OS_CPU_LINUX_SPARC_VM_THREADLS_LINUX_SPARC_HPP
-
-public:
-  static Thread* thread() {
-    return (Thread*) os::thread_local_storage_at(thread_index());
-  }
-
-#endif // OS_CPU_LINUX_SPARC_VM_THREADLS_LINUX_SPARC_HPP
--- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,85 +26,7 @@
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
 
-#ifndef _LP64
 void MacroAssembler::int3() {
   call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
 }
-
-#ifdef MINIMIZE_RAM_USAGE
-
-void MacroAssembler::get_thread(Register thread) {
-  // call pthread_getspecific
-  // void * pthread_getspecific(pthread_key_t key);
-  if (thread != rax) push(rax);
-  push(rcx);
-  push(rdx);
-
-  push(ThreadLocalStorage::thread_index());
-  call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
-  increment(rsp, wordSize);
-
-  pop(rdx);
-  pop(rcx);
-  if (thread != rax) {
-    mov(thread, rax);
-    pop(rax);
-  }
-}
-
-#else
-void MacroAssembler::get_thread(Register thread) {
-  movl(thread, rsp);
-  shrl(thread, PAGE_SHIFT);
-
-  ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr());
-  Address index(noreg, thread, Address::times_4);
-  ArrayAddress tls(tls_base, index);
-
-  movptr(thread, tls);
-}
-#endif // MINIMIZE_RAM_USAGE
-#else
-void MacroAssembler::int3() {
-  call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
-}
-
-void MacroAssembler::get_thread(Register thread) {
-  // call pthread_getspecific
-  // void * pthread_getspecific(pthread_key_t key);
-   if (thread != rax) {
-     push(rax);
-   }
-   push(rdi);
-   push(rsi);
-   push(rdx);
-   push(rcx);
-   push(r8);
-   push(r9);
-   push(r10);
-   // XXX
-   mov(r10, rsp);
-   andq(rsp, -16);
-   push(r10);
-   push(r11);
-
-   movl(rdi, ThreadLocalStorage::thread_index());
-   call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
-
-   pop(r11);
-   pop(rsp);
-   pop(r10);
-   pop(r9);
-   pop(r8);
-   pop(rcx);
-   pop(rdx);
-   pop(rsi);
-   pop(rdi);
-   if (thread != rax) {
-       mov(thread, rax);
-       pop(rax);
-   }
-}
-#endif
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -221,7 +221,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Map stack pointer (%esp) to thread pointer for faster TLS access
-//
-// Here we use a flat table for better performance. Getting current thread
-// is down to one memory access (read _sp_map[%esp>>12]) in generated code
-// and two in runtime code (-fPIC code needs an extra load for _sp_map).
-//
-// This code assumes stack page is not shared by different threads. It works
-// in 32-bit VM when page size is 4K (or a multiple of 4K, if that matters).
-//
-// Notice that _sp_map is allocated in the bss segment, which is ZFOD
-// (zero-fill-on-demand). While it reserves 4M address space upfront,
-// actual memory pages are committed on demand.
-//
-// If an application creates and destroys a lot of threads, usually the
-// stack space freed by a thread will soon get reused by new thread.
-// No memory page in _sp_map is wasted.
-//
-// However, it's still possible that we might end up populating &
-// committing a large fraction of the 4M table over time, but the actual
-// amount of live data in the table could be quite small. The max wastage
-// is less than 4M bytes. If it becomes an issue, we could use madvise()
-// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
-// MADV_DONTNEED on Linux keeps the virtual memory mapping, but zaps the
-// physical memory page (i.e. similar to MADV_FREE on Solaris).
-
-#if !defined(AMD64) && !defined(MINIMIZE_RAM_USAGE)
-Thread* ThreadLocalStorage::_sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    // nothing we can do here for user-level thread
-}
-
-void ThreadLocalStorage::pd_init() {
-  assert(align_size_down(os::vm_page_size(), PAGE_SIZE) == os::vm_page_size(),
-         "page size must be multiple of PAGE_SIZE");
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-  address stack_top = os::current_stack_base();
-  size_t stack_size = os::current_stack_size();
-
-  for (address p = stack_top - stack_size; p < stack_top; p += PAGE_SIZE) {
-    // pd_set_thread() is called with non-NULL value when a new thread is
-    // created/attached, or with NULL value when a thread is about to exit.
-    // If both "thread" and the corresponding _sp_map[] entry are non-NULL,
-    // they should have the same value. Otherwise it might indicate that the
-    // stack page is shared by multiple threads. However, a more likely cause
-    // for this assertion to fail is that an attached thread exited without
-    // detaching itself from VM, which is a program error and could cause VM
-    // to crash.
-    assert(thread == NULL || _sp_map[(uintptr_t)p >> PAGE_SHIFT] == NULL ||
-           thread == _sp_map[(uintptr_t)p >> PAGE_SHIFT],
-           "thread exited without detaching from VM??");
-    _sp_map[(uintptr_t)p >> PAGE_SHIFT] = thread;
-  }
-}
-#else
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-    // nothing we can do here for user-level thread
-}
-
-void ThreadLocalStorage::pd_init() {
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
-#endif // !AMD64 && !MINIMIZE_RAM_USAGE
--- a/hotspot/src/os_cpu/linux_x86/vm/threadLS_linux_x86.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
-
-  // Processor dependent parts of ThreadLocalStorage
-
-#if !defined(AMD64) && !defined(MINIMIZE_RAM_USAGE)
-
-  // map stack pointer to thread pointer - see notes in threadLS_linux_x86.cpp
-  #define SP_BITLENGTH  32
-  #define PAGE_SHIFT    12
-  #define PAGE_SIZE     (1UL << PAGE_SHIFT)
-  static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
-
-public:
-
-  static Thread** sp_map_addr() { return _sp_map; }
-
-  static Thread* thread() {
-    uintptr_t sp;
-    __asm__ volatile ("movl %%esp, %0" : "=r" (sp));
-    return _sp_map[sp >> PAGE_SHIFT];
-  }
-
-#else
-
-public:
-
-   static Thread* thread() {
-     return (Thread*) os::thread_local_storage_at(thread_index());
-   }
-
-#endif // AMD64 || MINIMIZE_RAM_USAGE
-
-#endif // OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
--- a/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -23,10 +23,4 @@
  *
  */
 
-#include "precompiled.hpp"
-#include "asm/assembler.hpp"
-#include "assembler_zero.inline.hpp"
-#include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
 // This file is intentionally empty
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -125,7 +125,7 @@
                         int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   SignalHandlerMark shm(t);
 
--- a/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-void ThreadLocalStorage::generate_code_for_get_thread() {
-  // nothing to do
-}
-
-void ThreadLocalStorage::pd_init() {
-  // nothing to do
-}
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread) {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
-
-// Processor dependent parts of ThreadLocalStorage
-
- public:
-  static Thread* thread() {
-    return (Thread*) os::thread_local_storage_at(thread_index());
-  }
-
-#endif // OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -290,7 +290,7 @@
                           int abort_if_unrecognized) {
   ucontext_t* uc = (ucontext_t*) ucVoid;
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// True thread-local variable
-__thread Thread * ThreadLocalStorage::_thr_current = NULL;
-
-// Implementations needed to support the shared API
-
-void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
-
-bool ThreadLocalStorage::_initialized = false;
-
-void ThreadLocalStorage::init() {
-  _initialized = true;
-}
-
-bool ThreadLocalStorage::is_initialized() {
-  return _initialized;
-}
-
-Thread* ThreadLocalStorage::get_thread_slow() {
-    return thread();
-}
-
-extern "C" Thread* get_thread() {
-  return ThreadLocalStorage::thread();
-}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
-#define OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
-
-// Solaris specific implementation involves simple, direct use
-// of a compiler-based thread-local variable
-
-private:
-  static __thread Thread * _thr_current;
-
-  static bool _initialized;  // needed for shared API
-
-public:
-  static inline Thread* thread();
-
-#endif // OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
--- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -25,8 +25,6 @@
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-#include "runtime/thread.inline.hpp"
 
 void MacroAssembler::int3() {
   push(rax);
@@ -37,33 +35,3 @@
   pop(rdx);
   pop(rax);
 }
-
-// This is simply a call to ThreadLocalStorage::thread()
-void MacroAssembler::get_thread(Register thread) {
-  if (thread != rax) {
-    push(rax);
-  }
-  push(rdi);
-  push(rsi);
-  push(rdx);
-  push(rcx);
-  push(r8);
-  push(r9);
-  push(r10);
-  push(r11);
-
-  call(RuntimeAddress(CAST_FROM_FN_PTR(address, ThreadLocalStorage::thread)));
-
-  pop(r11);
-  pop(r10);
-  pop(r9);
-  pop(r8);
-  pop(rcx);
-  pop(rdx);
-  pop(rsi);
-  pop(rdi);
-  if (thread != rax) {
-    movl(thread, rax);
-    pop(rax);
-  }
-}
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -346,7 +346,7 @@
   }
 #endif // !AMD64
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();  // slow & steady
+  Thread* t = Thread::current_or_null_safe();
 
   // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
   // (no destructors can be run)
--- a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// True thread-local variable
-__thread Thread * ThreadLocalStorage::_thr_current = NULL;
-
-// Implementations needed to support the shared API
-
-void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
-
-bool ThreadLocalStorage::_initialized = false;
-
-void ThreadLocalStorage::init() {
-  _initialized = true;
-}
-
-bool ThreadLocalStorage::is_initialized() {
-  return _initialized;
-}
-
-Thread* ThreadLocalStorage::get_thread_slow() {
-    return thread();
-}
-
-extern "C" Thread* get_thread() {
-  return ThreadLocalStorage::thread();
-}
--- a/hotspot/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
-#define OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
-
-// Solaris specific implementation involves simple, direct use
-// of a compiler-based thread-local variable
-
-private:
-  static __thread Thread * _thr_current;
-
-  static bool _initialized;  // needed for shared API
-
-public:
-  static inline Thread* thread();
-
-#endif // OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
--- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
 
 void MacroAssembler::int3() {
   emit_int8((unsigned char)0xCC);
@@ -58,44 +56,11 @@
 
   prefix(FS_segment);
   movptr(thread, null);
-  assert(ThreadLocalStorage::get_thread_ptr_offset() != 0,
+  assert(os::win32::get_thread_ptr_offset() != 0,
          "Thread Pointer Offset has not been initialized");
-  movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset()));
+  movl(thread, Address(thread, os::win32::get_thread_ptr_offset()));
 }
-#else
-// call (Thread*)TlsGetValue(thread_index());
-void MacroAssembler::get_thread(Register thread) {
-   if (thread != rax) {
-     push(rax);
-   }
-   push(rdi);
-   push(rsi);
-   push(rdx);
-   push(rcx);
-   push(r8);
-   push(r9);
-   push(r10);
-   // XXX
-   mov(r10, rsp);
-   andq(rsp, -16);
-   push(r10);
-   push(r11);
 
-   movl(c_rarg0, ThreadLocalStorage::thread_index());
-   call(RuntimeAddress((address)TlsGetValue));
+// #else - use shared x86 implementation in cpu/x86/vm/macroAssembler_x86.cpp
 
-   pop(r11);
-   pop(rsp);
-   pop(r10);
-   pop(r9);
-   pop(r8);
-   pop(rcx);
-   pop(rdx);
-   pop(rsi);
-   pop(rdi);
-   if (thread != rax) {
-       mov(thread, rax);
-       pop(rax);
-   }
-}
 #endif
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -85,14 +85,14 @@
     //
     volatile Thread* wrapperthread = thread;
 
-    if ( ThreadLocalStorage::get_thread_ptr_offset() == 0 ) {
+    if (os::win32::get_thread_ptr_offset() == 0) {
       int thread_ptr_offset;
       __asm {
         lea eax, dword ptr wrapperthread;
         sub eax, dword ptr FS:[0H];
         mov thread_ptr_offset, eax
       };
-      ThreadLocalStorage::set_thread_ptr_offset(thread_ptr_offset);
+      os::win32::set_thread_ptr_offset(thread_ptr_offset);
     }
 #ifdef ASSERT
     // Verify that the offset hasn't changed since we initally captured
@@ -105,7 +105,7 @@
         sub eax, dword ptr FS:[0H];
         mov test_thread_ptr_offset, eax
       };
-      assert(test_thread_ptr_offset == ThreadLocalStorage::get_thread_ptr_offset(),
+      assert(test_thread_ptr_offset == os::win32::get_thread_ptr_offset(),
              "thread pointer offset from SEH changed");
     }
 #endif // ASSERT
--- a/hotspot/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Provides an entry point we can link against and
-// a buffer we can emit code into. The buffer is
-// filled by ThreadLocalStorage::generate_code_for_get_thread
-// and called from ThreadLocalStorage::thread()
-
-int ThreadLocalStorage::_thread_ptr_offset = 0;
-
-static void call_wrapper_dummy() {}
-
-// We need to call the os_exception_wrapper once so that it sets
-// up the offset from FS of the thread pointer.
-void ThreadLocalStorage::generate_code_for_get_thread() {
-      os::os_exception_wrapper( (java_call_t)call_wrapper_dummy,
-                                NULL, NULL, NULL, NULL);
-}
-
-void ThreadLocalStorage::pd_init() { }
-
-void ThreadLocalStorage::pd_set_thread(Thread* thread)  {
-  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
-}
--- a/hotspot/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_CPU_WINDOWS_X86_VM_THREADLS_WINDOWS_X86_HPP
-#define OS_CPU_WINDOWS_X86_VM_THREADLS_WINDOWS_X86_HPP
-
-// Processor dependent parts of ThreadLocalStorage
-
-protected:
-
-  static int _thread_ptr_offset;
-
-public:
-
-  // Java Thread
-  static inline Thread* thread() {
-    return (Thread*)TlsGetValue(thread_index());
-  }
-
-  static inline Thread* get_thread() {
-    return (Thread*)TlsGetValue(thread_index());
-  }
-
-  static inline void set_thread_ptr_offset( int offset ) { _thread_ptr_offset = offset; }
-
-  static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
-
-#endif // OS_CPU_WINDOWS_X86_VM_THREADLS_WINDOWS_X86_HPP
--- a/hotspot/src/share/vm/code/nmethod.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -2609,7 +2609,7 @@
   int cont_offset = ImplicitExceptionTable(this).at( exception_offset );
 #ifdef ASSERT
   if (cont_offset == 0) {
-    Thread* thread = ThreadLocalStorage::get_thread_slow();
+    Thread* thread = Thread::current();
     ResetNoHandleMark rnm; // Might be called from LEAF/QUICK ENTRY
     HandleMark hm(thread);
     ResourceMark rm(thread);
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -144,9 +144,6 @@
     _cmst = NULL;
     Terminator_lock->notify();
   }
-
-  // Thread destructor usually does this..
-  ThreadLocalStorage::set_thread(NULL);
 }
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -123,7 +123,7 @@
   // Resets the hot card cache and discards the entries.
   void reset_hot_cache() {
     assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
-    assert(Thread::current_noinline()->is_VM_thread(), "Current thread should be the VMthread");
+    assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
     if (default_use_cache()) {
         reset_hot_cache_internal();
     }
--- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -96,7 +95,6 @@
 void GCTaskThread::run() {
   // Set up the thread for stack overflow support
   this->record_stack_base_and_size();
-  this->initialize_thread_local_storage();
   this->initialize_named_thread();
   // Bind yourself to your processor.
   if (processor_id() != GCTaskManager::sentinel_worker()) {
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -51,7 +51,6 @@
 
 void ConcurrentGCThread::initialize_in_thread() {
   this->record_stack_base_and_size();
-  this->initialize_thread_local_storage();
   this->initialize_named_thread();
   this->set_active_handles(JNIHandleBlock::allocate_block());
   // From this time Thread::current() should be working.
@@ -74,9 +73,6 @@
     _has_terminated = true;
     Terminator_lock->notify();
   }
-
-  // Thread destructor usually does this..
-  ThreadLocalStorage::set_thread(NULL);
 }
 
 static void _sltLoop(JavaThread* thread, TRAPS) {
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -275,7 +275,6 @@
 }
 
 void AbstractGangWorker::initialize() {
-  this->initialize_thread_local_storage();
   this->record_stack_base_and_size();
   this->initialize_named_thread();
   assert(_gang != NULL, "No gang to run in");
--- a/hotspot/src/share/vm/memory/allocation.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/memory/allocation.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -790,7 +790,7 @@
 
 ReallocMark::ReallocMark() {
 #ifdef ASSERT
-  Thread *thread = ThreadLocalStorage::get_thread_slow();
+  Thread *thread = Thread::current();
   _nesting = thread->resource_area()->nesting();
 #endif
 }
--- a/hotspot/src/share/vm/memory/resourceArea.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,7 +121,7 @@
     debug_only(_area->_nesting++;)
     assert( _area->_nesting > 0, "must stack allocate RMs" );
 #ifdef ASSERT
-    Thread* thread = ThreadLocalStorage::thread();
+    Thread* thread = Thread::current_or_null();
     if (thread != NULL) {
       _thread = thread;
       _previous_resource_mark = thread->current_resource_mark();
--- a/hotspot/src/share/vm/oops/oopsHierarchy.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/oops/oopsHierarchy.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -35,7 +35,7 @@
   assert (CheckUnhandledOops, "should only call when CheckUnhandledOops");
   if (!Universe::is_fully_initialized()) return;
   // This gets expensive, which is why checking unhandled oops is on a switch.
-  Thread* t = ThreadLocalStorage::thread();
+  Thread* t = Thread::current_or_null();
   if (t != NULL && t->is_Java_thread()) {
      frame fr = os::current_frame();
      // This points to the oop creator, I guess current frame points to caller
@@ -48,7 +48,7 @@
   assert (CheckUnhandledOops, "should only call when CheckUnhandledOops");
   if (!Universe::is_fully_initialized()) return;
   // This gets expensive, which is why checking unhandled oops is on a switch.
-  Thread* t = ThreadLocalStorage::thread();
+  Thread* t = Thread::current_or_null();
   if (t != NULL && t->is_Java_thread()) {
     t->unhandled_oops()->unregister_unhandled_oop(this);
   }
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -203,7 +203,6 @@
 # include "runtime/stubRoutines.hpp"
 # include "runtime/synchronizer.hpp"
 # include "runtime/thread.hpp"
-# include "runtime/threadLocalStorage.hpp"
 # include "runtime/timer.hpp"
 # include "runtime/unhandledOops.hpp"
 # include "runtime/vframe.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/prims/jni.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -4175,7 +4175,7 @@
   }
   */
 
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null();
   if (t != NULL) {
     // If the thread has been attached this operation is a no-op
     *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
@@ -4190,10 +4190,8 @@
   // initializing the Java level thread object. Hence, the correct state must
   // be set in order for the Safepoint code to deal with it correctly.
   thread->set_thread_state(_thread_in_vm);
-  // Must do this before initialize_thread_local_storage
   thread->record_stack_base_and_size();
-
-  thread->initialize_thread_local_storage();
+  thread->initialize_thread_current();
 
   if (!os::create_attached_thread(thread)) {
     delete thread;
@@ -4300,8 +4298,8 @@
 
   JNIWrapper("DetachCurrentThread");
 
-  // If the thread has been deattacted the operations is a no-op
-  if (ThreadLocalStorage::thread() == NULL) {
+  // If the thread has already been detached the operation is a no-op
+  if (Thread::current_or_null() == NULL) {
   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
     return JNI_OK;
   }
@@ -4358,7 +4356,7 @@
 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
 #endif // !JVMPI_VERSION_1
 
-  Thread* thread = ThreadLocalStorage::thread();
+  Thread* thread = Thread::current_or_null();
   if (thread != NULL && thread->is_Java_thread()) {
     if (Threads::is_supported_jni_version_including_1_1(version)) {
       *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -87,9 +87,9 @@
 #define JNI_ENTRY_CHECKED(result_type, header)                           \
 extern "C" {                                                             \
   result_type JNICALL header {                                           \
-    JavaThread* thr = (JavaThread*)ThreadLocalStorage::get_thread_slow();\
+    JavaThread* thr = (JavaThread*) Thread::current_or_null();           \
     if (thr == NULL || !thr->is_Java_thread()) {                         \
-      tty->print_cr("%s", fatal_using_jnienv_in_nonjava);                      \
+      tty->print_cr("%s", fatal_using_jnienv_in_nonjava);                \
       os::abort(true);                                                   \
     }                                                                    \
     JNIEnv* xenv = thr->jni_environment();                               \
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Fri Dec 04 04:06:37 2015 -0500
@@ -494,7 +494,7 @@
   }</xsl:text>  
 
       <xsl:text>  
-  Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); </xsl:text>
+  Thread* this_thread = Thread::current_or_null(); </xsl:text>
 
       <xsl:apply-templates select="." mode="transition"/>
     </xsl:when>
@@ -528,7 +528,7 @@
     </xsl:if>
     <xsl:text>    return JVMTI_ERROR_WRONG_PHASE;
   }
-  Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); </xsl:text>
+  Thread* this_thread = Thread::current_or_null(); </xsl:text>
       <xsl:apply-templates select="." mode="transition"/>
       </xsl:if>
     </xsl:otherwise>
@@ -558,7 +558,7 @@
       <xsl:choose>
         <xsl:when test="count(@callbacksafe)=0 or not(contains(@callbacksafe,'safe'))">
           <xsl:text>  if (Threads::number_of_threads() != 0) {
-    Thread* this_thread = (Thread*)ThreadLocalStorage::thread();</xsl:text>
+    Thread* this_thread = Thread::current_or_null();</xsl:text>
         </xsl:when>
         <xsl:otherwise>
 
@@ -567,7 +567,7 @@
   if (Threads::number_of_threads() == 0) {
     transition = false;
   } else {
-    this_thread = (Thread*)ThreadLocalStorage::thread();
+    this_thread = Thread::current_or_null();
     transition = ((this_thread != NULL) &amp;&amp; !this_thread->is_VM_thread() &amp;&amp; !this_thread->is_ConcurrentGC_thread());
   }
   if (transition) {</xsl:text>
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -374,7 +374,7 @@
   }
 
   if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
-    JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread();
+    JavaThread* current_thread = JavaThread::current();
     // transition code: native to VM
     ThreadInVMfromNative __tiv(current_thread);
     VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
@@ -1901,7 +1901,7 @@
 
 // Collect all the vm internally allocated objects which are visible to java world
 void JvmtiExport::record_vm_internal_object_allocation(oop obj) {
-  Thread* thread = ThreadLocalStorage::thread();
+  Thread* thread = Thread::current_or_null();
   if (thread != NULL && thread->is_Java_thread())  {
     // Can not take safepoint here.
     No_Safepoint_Verifier no_sfpt;
@@ -2436,7 +2436,7 @@
   if (!JvmtiExport::should_post_vm_object_alloc()) {
     return;
   }
-  Thread* thread = ThreadLocalStorage::thread();
+  Thread* thread = Thread::current_or_null();
   if (thread != NULL && thread->is_Java_thread())  {
     JavaThread* current_thread = (JavaThread*)thread;
     JvmtiThreadState *state = current_thread->jvmti_thread_state();
--- a/hotspot/src/share/vm/prims/jvmtiUtil.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiUtil.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@
     if (Threads::number_of_threads() == 0) {
       return JvmtiUtil::single_threaded_resource_area();
     }
-    thread = ThreadLocalStorage::thread();
+    thread = Thread::current_or_null();
     if (thread == NULL) {
       return JvmtiUtil::single_threaded_resource_area();
     }
--- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -32,7 +32,6 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/os.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
 #include "runtime/vframe.hpp"
 #include "utilities/preserveException.hpp"
 
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -562,7 +562,7 @@
 #define JVM_ENTRY_NO_ENV(result_type, header)                        \
 extern "C" {                                                         \
   result_type JNICALL header {                                       \
-    JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();  \
+    JavaThread* thread = JavaThread::current();                      \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
     VM_ENTRY_BASE(result_type, header, thread)
--- a/hotspot/src/share/vm/runtime/java.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/java.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -512,10 +512,10 @@
 }
 
 void vm_exit(int code) {
-  Thread* thread = ThreadLocalStorage::is_initialized() ?
-    ThreadLocalStorage::get_thread_slow() : NULL;
+  Thread* thread =
+      ThreadLocalStorage::is_initialized() ? Thread::current_or_null() : NULL;
   if (thread == NULL) {
-    // we have serious problems -- just exit
+    // very early initialization failure -- just exit
     vm_direct_exit(code);
   }
 
@@ -551,8 +551,7 @@
   // Calling 'exit_globals()' will disable thread-local-storage and cause all
   // kinds of assertions to trigger in debug mode.
   if (is_init_completed()) {
-    Thread* thread = ThreadLocalStorage::is_initialized() ?
-                     ThreadLocalStorage::get_thread_slow() : NULL;
+    Thread* thread = Thread::current_or_null();
     if (thread != NULL && thread->is_Java_thread()) {
       // We are leaving the VM, set state to native (in case any OS exit
       // handlers call back to the VM)
@@ -606,7 +605,7 @@
   // If there are exceptions on this thread it must be cleared
   // first and here. Any future calls to EXCEPTION_MARK requires
   // that no pending exceptions exist.
-  Thread *THREAD = Thread::current();
+  Thread *THREAD = Thread::current(); // can't be NULL
   if (HAS_PENDING_EXCEPTION) {
     CLEAR_PENDING_EXCEPTION;
   }
--- a/hotspot/src/share/vm/runtime/mutex.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/mutex.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1035,10 +1035,10 @@
  Exeunt:
     assert(ILocked(), "invariant");
     assert(_owner == NULL, "invariant");
-    // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage
+    // This can potentially be called by non-java Threads. Thus, the Thread::current_or_null()
     // might return NULL. Don't call set_owner since it will break on an NULL owner
     // Consider installing a non-null "ANON" distinguished value instead of just NULL.
-    _owner = ThreadLocalStorage::thread();
+    _owner = Thread::current_or_null();
     return;
   }
 
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -27,7 +27,6 @@
 #include "runtime/os.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
 #include "runtime/vmThread.hpp"
 
 // Mutexes used in the VM (see comment in mutexLocker.hpp):
--- a/hotspot/src/share/vm/runtime/os.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/os.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -420,28 +420,6 @@
     }
 #endif
   }
-  static jboolean onLoaded = JNI_FALSE;
-  if (onLoaded) {
-    // We may have to wait to fire OnLoad until TLS is initialized.
-    if (ThreadLocalStorage::is_initialized()) {
-      // The JNI_OnLoad handling is normally done by method load in
-      // java.lang.ClassLoader$NativeLibrary, but the VM loads the base library
-      // explicitly so we have to check for JNI_OnLoad as well
-      const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
-      JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(
-          JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0]));
-      if (JNI_OnLoad != NULL) {
-        JavaThread* thread = JavaThread::current();
-        ThreadToNativeFromVM ttn(thread);
-        HandleMark hm(thread);
-        jint ver = (*JNI_OnLoad)(&main_vm, NULL);
-        onLoaded = JNI_TRUE;
-        if (!Threads::is_supported_jni_version_including_1_1(ver)) {
-          vm_exit_during_initialization("Unsupported JNI version");
-        }
-      }
-    }
-  }
   return _native_java_library;
 }
 
@@ -574,7 +552,7 @@
   // exists and has crash protection.
   WatcherThread *wt = WatcherThread::watcher_thread();
   if (wt != NULL && wt->has_crash_protection()) {
-    Thread* thread = ThreadLocalStorage::get_thread_slow();
+    Thread* thread = Thread::current_or_null();
     if (thread == wt) {
       assert(!wt->has_crash_protection(),
           "Can't malloc with crash protection from WatcherThread");
--- a/hotspot/src/share/vm/runtime/os.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/os.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -670,12 +670,6 @@
   static jlong current_file_offset(int fd);
   static jlong seek_to_file_offset(int fd, jlong offset);
 
-  // Thread Local Storage
-  static int   allocate_thread_local_storage();
-  static void  thread_local_storage_at_put(int index, void* value);
-  static void* thread_local_storage_at(int index);
-  static void  free_thread_local_storage(int index);
-
   // Retrieve native stack frames.
   // Parameter:
   //   stack:  an array to storage stack pointers.
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -30,7 +30,6 @@
 #include "interpreter/linkResolver.hpp"
 #include "memory/allocation.hpp"
 #include "memory/resourceArea.hpp"
-#include "runtime/threadLocalStorage.hpp"
 #include "utilities/hashtable.hpp"
 #include "utilities/macros.hpp"
 
--- a/hotspot/src/share/vm/runtime/thread.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -78,7 +78,6 @@
 #include "runtime/task.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
-#include "runtime/threadLocalStorage.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/vframe_hp.hpp"
@@ -142,6 +141,10 @@
 
 #endif // ndef DTRACE_ENABLED
 
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+// Current thread is maintained as a thread-local variable
+THREAD_LOCAL_DECL Thread* Thread::_thr_current = NULL;
+#endif
 
 // Class hierarchy
 // - Thread
@@ -281,22 +284,22 @@
 #endif // ASSERT
 }
 
-// Non-inlined version to be used where thread.inline.hpp shouldn't be included.
-Thread* Thread::current_noinline() {
-  return Thread::current();
+void Thread::initialize_thread_current() {
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+  assert(_thr_current == NULL, "Thread::current already initialized");
+  _thr_current = this;
+#endif
+  assert(ThreadLocalStorage::thread() == NULL, "ThreadLocalStorage::thread already initialized");
+  ThreadLocalStorage::set_thread(this);
+  assert(Thread::current() == ThreadLocalStorage::thread(), "TLS mismatch!");
 }
 
-void Thread::initialize_thread_local_storage() {
-  // Note: Make sure this method only calls
-  // non-blocking operations. Otherwise, it might not work
-  // with the thread-startup/safepoint interaction.
-
-  // During Java thread startup, safepoint code should allow this
-  // method to complete because it may need to allocate memory to
-  // store information for the new thread.
-
-  // initialize structure dependent on thread local storage
-  ThreadLocalStorage::set_thread(this);
+void Thread::clear_thread_current() {
+  assert(Thread::current() == ThreadLocalStorage::thread(), "TLS mismatch!");
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+  _thr_current = NULL;
+#endif
+  ThreadLocalStorage::set_thread(NULL);
 }
 
 void Thread::record_stack_base_and_size() {
@@ -364,15 +367,12 @@
 
   delete _SR_lock;
 
-  // clear thread local storage if the Thread is deleting itself
+  // clear Thread::current if thread is deleting itself.
+  // Needed to ensure JNI correctly detects non-attached threads.
   if (this == Thread::current()) {
-    ThreadLocalStorage::set_thread(NULL);
-  } else {
-    // In the case where we're not the current thread, invalidate all the
-    // caches in case some code tries to get the current thread or the
-    // thread that was destroyed, and gets stale information.
-    ThreadLocalStorage::invalidate_all();
+    clear_thread_current();
   }
+
   CHECK_UNHANDLED_OOPS_ONLY(if (CheckUnhandledOops) delete unhandled_oops();)
 }
 
@@ -1273,7 +1273,6 @@
   assert(this == watcher_thread(), "just checking");
 
   this->record_stack_base_and_size();
-  this->initialize_thread_local_storage();
   this->set_native_thread_name(this->name());
   this->set_active_handles(JNIHandleBlock::allocate_block());
   while (true) {
@@ -1326,9 +1325,6 @@
     _watcher_thread = NULL;
     Terminator_lock->notify();
   }
-
-  // Thread destructor usually does this..
-  ThreadLocalStorage::set_thread(NULL);
 }
 
 void WatcherThread::start() {
@@ -1663,9 +1659,6 @@
   // Record real stack base and size.
   this->record_stack_base_and_size();
 
-  // Initialize thread local storage; set before calling MutexLocker
-  this->initialize_thread_local_storage();
-
   this->create_stack_guard_pages();
 
   this->cache_global_variables();
@@ -1997,8 +1990,7 @@
 
 
 JavaThread* JavaThread::active() {
-  Thread* thread = ThreadLocalStorage::thread();
-  assert(thread != NULL, "just checking");
+  Thread* thread = Thread::current();
   if (thread->is_Java_thread()) {
     return (JavaThread*) thread;
   } else {
@@ -3407,7 +3399,7 @@
   jint adjust_after_os_result = Arguments::adjust_after_os();
   if (adjust_after_os_result != JNI_OK) return adjust_after_os_result;
 
-  // initialize TLS
+  // Initialize library-based TLS
   ThreadLocalStorage::init();
 
   // Initialize output stream logging
@@ -3444,14 +3436,9 @@
   // Attach the main thread to this os thread
   JavaThread* main_thread = new JavaThread();
   main_thread->set_thread_state(_thread_in_vm);
-  // must do this before set_active_handles and initialize_thread_local_storage
-  // Note: on solaris initialize_thread_local_storage() will (indirectly)
-  // change the stack size recorded here to one based on the java thread
-  // stacksize. This adjusted size is what is used to figure the placement
-  // of the guard pages.
+  main_thread->initialize_thread_current();
+  // must do this before set_active_handles
   main_thread->record_stack_base_and_size();
-  main_thread->initialize_thread_local_storage();
-
   main_thread->set_active_handles(JNIHandleBlock::allocate_block());
 
   if (!main_thread->set_as_starting_thread()) {
--- a/hotspot/src/share/vm/runtime/thread.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -102,6 +102,12 @@
 class Thread: public ThreadShadow {
   friend class VMStructs;
  private:
+
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+  // Current thread is maintained as a thread-local variable
+  static THREAD_LOCAL_DECL Thread* _thr_current;
+#endif
+
   // Exception handling
   // (Note: _pending_exception and friends are in ThreadShadow)
   //oop       _pending_exception;                // pending exception for current thread
@@ -260,7 +266,6 @@
   friend class No_Alloc_Verifier;
   friend class No_Safepoint_Verifier;
   friend class Pause_No_Safepoint_Verifier;
-  friend class ThreadLocalStorage;
   friend class GC_locker;
 
   ThreadLocalAllocBuffer _tlab;                 // Thread-local eden
@@ -307,9 +312,12 @@
   Thread();
   virtual ~Thread();
 
-  // initializtion
-  void initialize_thread_local_storage();
+  // Manage Thread::current()
+  void initialize_thread_current();
+  private:
+  void clear_thread_current(); // needed for detaching JNI threads
 
+  public:
   // thread entry point
   virtual void run();
 
@@ -337,10 +345,13 @@
 
   virtual char* name() const { return (char*)"Unknown thread"; }
 
-  // Returns the current thread
+  // Returns the current thread (ASSERTS if NULL)
   static inline Thread* current();
-  // ... without having to include thread.inline.hpp.
-  static Thread* current_noinline();
+  // Returns the current thread, or NULL if not attached
+  static inline Thread* current_or_null();
+  // Returns the current thread, or NULL if not attached, and is
+  // safe for use from signal-handlers
+  static inline Thread* current_or_null_safe();
 
   // Common thread operations
   static void set_priority(Thread* thread, ThreadPriority priority);
@@ -649,25 +660,22 @@
 };
 
 // Inline implementation of Thread::current()
-// Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of
-// startup.
-// ThreadLocalStorage::thread is warm -- it's called > 16K times in the same
-// period.   This is inlined in thread_<os_family>.inline.hpp.
+inline Thread* Thread::current() {
+  Thread* current = current_or_null();
+  assert(current != NULL, "Thread::current() called on detached thread");
+  return current;
+}
 
-inline Thread* Thread::current() {
-#ifdef ASSERT
-  // This function is very high traffic. Define PARANOID to enable expensive
-  // asserts.
-#ifdef PARANOID
-  // Signal handler should call ThreadLocalStorage::get_thread_slow()
-  Thread* t = ThreadLocalStorage::get_thread_slow();
-  assert(t != NULL && !t->is_inside_signal_handler(),
-         "Don't use Thread::current() inside signal handler");
+inline Thread* Thread::current_or_null() {
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+  return _thr_current;
+#else
+  return ThreadLocalStorage::thread();
 #endif
-#endif
-  Thread* thread = ThreadLocalStorage::thread();
-  assert(thread != NULL, "just checking");
-  return thread;
+}
+
+inline Thread* Thread::current_or_null_safe() {
+  return ThreadLocalStorage::thread();
 }
 
 // Name support for threads.  non-JavaThread subclasses with multiple
@@ -1842,8 +1850,8 @@
 
 // Inline implementation of JavaThread::current
 inline JavaThread* JavaThread::current() {
-  Thread* thread = ThreadLocalStorage::thread();
-  assert(thread != NULL && thread->is_Java_thread(), "just checking");
+  Thread* thread = Thread::current();
+  assert(thread->is_Java_thread(), "just checking");
   return (JavaThread*)thread;
 }
 
--- a/hotspot/src/share/vm/runtime/thread.inline.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/thread.inline.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,21 +30,6 @@
 #include "runtime/atomic.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/thread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_aix
-# include "thread_aix.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
 
 #undef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
 
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "runtime/os.inline.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-// Solaris no longer has this kind of ThreadLocalStorage implementation.
-// This will be removed from all platforms in the near future.
-
-#ifndef SOLARIS
-
-// static member initialization
-int ThreadLocalStorage::_thread_index = -1;
-
-Thread* ThreadLocalStorage::get_thread_slow() {
-  return (Thread*) os::thread_local_storage_at(ThreadLocalStorage::thread_index());
-}
-
-void ThreadLocalStorage::set_thread(Thread* thread) {
-  pd_set_thread(thread);
-
-  // The following ensure that any optimization tricks we have tried
-  // did not backfire on us:
-  guarantee(get_thread()      == thread, "must be the same thread, quickly");
-  guarantee(get_thread_slow() == thread, "must be the same thread, slowly");
-}
-
-void ThreadLocalStorage::init() {
-  assert(!is_initialized(),
-         "More than one attempt to initialize threadLocalStorage");
-  pd_init();
-  set_thread_index(os::allocate_thread_local_storage());
-  generate_code_for_get_thread();
-}
-
-bool ThreadLocalStorage::is_initialized() {
-    return (thread_index() != -1);
-}
-
-#endif // SOLARIS
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -25,86 +25,26 @@
 #ifndef SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
 #define SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
 
-#include "gc/shared/gcUtil.hpp"
-#include "runtime/os.hpp"
 #include "utilities/top.hpp"
 
-// Interface for thread local storage
+// forward-decl as we can't have an include cycle
+class Thread;
 
-// Fast variant of ThreadLocalStorage::get_thread_slow
-extern "C" Thread*   get_thread();
-
-// Get raw thread id: e.g., %g7 on sparc, fs or gs on x86
-extern "C" uintptr_t _raw_thread_id();
+// Wrapper class for library-based (as opposed to compiler-based)
+// thread-local storage (TLS). All platforms require this for
+// signal-handler based TLS access (which while not strictly async-signal
+// safe in theory, is and has-been for a long time, in practice).
+// Platforms without compiler-based TLS (i.e. __thread storage-class modifier)
+// will use this implementation for all TLS access - see thread.hpp/cpp
 
 class ThreadLocalStorage : AllStatic {
 
  // Exported API
  public:
-  static void    set_thread(Thread* thread);
-  static Thread* get_thread_slow();
-  static void    invalidate_all() { pd_invalidate_all(); }
+  static Thread* thread(); // return current thread, if attached
+  static void    set_thread(Thread* thread); // set current thread
   static void    init();
-  static bool    is_initialized();
-
-  // Machine dependent stuff
-#ifdef TARGET_OS_ARCH_linux_x86
-# include "threadLS_linux_x86.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_linux_sparc
-# include "threadLS_linux_sparc.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_linux_zero
-# include "threadLS_linux_zero.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_solaris_x86
-# include "threadLS_solaris_x86.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_solaris_sparc
-# include "threadLS_solaris_sparc.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_windows_x86
-# include "threadLS_windows_x86.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_linux_arm
-# include "threadLS_linux_arm.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_linux_ppc
-# include "threadLS_linux_ppc.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_linux_aarch64
-# include "threadLS_linux_aarch64.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_aix_ppc
-# include "threadLS_aix_ppc.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_bsd_x86
-# include "threadLS_bsd_x86.hpp"
-#endif
-#ifdef TARGET_OS_ARCH_bsd_zero
-# include "threadLS_bsd_zero.hpp"
-#endif
-
-#ifndef SOLARIS
- public:
-  // Accessor
-  static inline int  thread_index()              { return _thread_index; }
-  static inline void set_thread_index(int index) { _thread_index = index; }
-
- private:
-  static int     _thread_index;
-
-  static void    generate_code_for_get_thread();
-
-  // Processor dependent parts of set_thread and initialization
-  static void pd_set_thread(Thread* thread);
-  static void pd_init();
-
-#endif // SOLARIS
-
-  // Invalidate any thread cacheing or optimization schemes.
-  static void pd_invalidate_all();
-
+  static bool    is_initialized(); // can't use TLS prior to initialization
 };
 
 #endif // SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -240,7 +240,6 @@
 void VMThread::run() {
   assert(this == vm_thread(), "check");
 
-  this->initialize_thread_local_storage();
   this->initialize_named_thread();
   this->record_stack_base_and_size();
   // Notify_lock wait checks on active_handles() to rewait in
@@ -308,9 +307,6 @@
     _terminate_lock->notify();
   }
 
-  // Thread destructor usually does this.
-  ThreadLocalStorage::set_thread(NULL);
-
   // Deletion must be done synchronously by the JNI DestroyJavaVM thread
   // so that the VMThread deletion completes before the main thread frees
   // up the CodeHeap.
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -378,7 +378,7 @@
 int VM_Exit::set_vm_exited() {
   CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::LastStep);
 
-  Thread * thr_cur = ThreadLocalStorage::get_thread_slow();
+  Thread * thr_cur = Thread::current();
 
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
 
@@ -400,7 +400,7 @@
   // to wait for threads in _thread_in_native state to be quiescent.
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
 
-  Thread * thr_cur = ThreadLocalStorage::get_thread_slow();
+  Thread * thr_cur = Thread::current();
   Monitor timer(Mutex::leaf, "VM_Exit timer", true,
                 Monitor::_safepoint_check_never);
 
@@ -477,7 +477,7 @@
 
 void VM_Exit::wait_if_vm_exited() {
   if (_vm_exited &&
-      ThreadLocalStorage::get_thread_slow() != _shutdown_thread) {
+      Thread::current_or_null() != _shutdown_thread) {
     // _vm_exited is set at safepoint, and the Threads_lock is never released
     // we will block here until the process dies
     Threads_lock->lock_without_safepoint_check();
--- a/hotspot/src/share/vm/utilities/debug.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -215,7 +215,7 @@
   if (Debugging || error_is_suppressed(file, line)) return;
   va_list detail_args;
   va_start(detail_args, detail_fmt);
-  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, error_msg, detail_fmt, detail_args);
+  VMError::report_and_die(Thread::current_or_null(), file, line, error_msg, detail_fmt, detail_args);
   va_end(detail_args);
 }
 
@@ -224,7 +224,7 @@
   if (Debugging || error_is_suppressed(file, line)) return;
   va_list detail_args;
   va_start(detail_args, detail_fmt);
-  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, "fatal error", detail_fmt, detail_args);
+  VMError::report_and_die(Thread::current_or_null(), file, line, "fatal error", detail_fmt, detail_args);
   va_end(detail_args);
 }
 
@@ -233,7 +233,7 @@
   if (Debugging) return;
   va_list detail_args;
   va_start(detail_args, detail_fmt);
-  VMError::report_and_die(ThreadLocalStorage::get_thread_slow(), file, line, size, vm_err_type, detail_fmt, detail_args);
+  VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
   va_end(detail_args);
 
   // The UseOSErrorReporting option in report_and_die() may allow a return
@@ -536,7 +536,7 @@
 #endif // !PRODUCT
 
 extern "C" void ps() { // print stack
-  if (Thread::current() == NULL) return;
+  if (Thread::current_or_null() == NULL) return;
   Command c("ps");
 
 
@@ -615,7 +615,7 @@
 #endif // !PRODUCT
 
 extern "C" void pss() { // print all stacks
-  if (Thread::current() == NULL) return;
+  if (Thread::current_or_null() == NULL) return;
   Command c("pss");
   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
 }
@@ -772,7 +772,7 @@
 extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
   Command c("pns");
   static char buf[O_BUFLEN];
-  Thread* t = ThreadLocalStorage::get_thread_slow();
+  Thread* t = Thread::current_or_null();
   // Call generic frame constructor (certain arguments may be ignored)
   frame fr(sp, fp, pc);
   print_native_stack(tty, fr, t, buf, sizeof(buf));
--- a/hotspot/src/share/vm/utilities/events.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/events.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -29,7 +29,6 @@
 #include "runtime/osThread.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
-#include "runtime/threadLocalStorage.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/events.hpp"
 
--- a/hotspot/src/share/vm/utilities/events.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/events.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -248,8 +248,8 @@
 
 template <class T>
 inline void EventLogBase<T>::print_log_on(outputStream* out) {
-  if (ThreadLocalStorage::get_thread_slow() == NULL) {
-    // Not a regular Java thread so don't bother locking
+  if (Thread::current_or_null() == NULL) {
+    // Not yet attached? Don't try to use locking
     print_log_impl(out);
   } else {
     MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
--- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -326,4 +326,8 @@
 #define JLONG_FORMAT           "%ld"
 #endif // _LP64 && __APPLE__
 
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+#define THREAD_LOCAL_DECL __thread
+#endif
+
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
--- a/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -273,4 +273,8 @@
 
 #define offset_of(klass,field) offsetof(klass,field)
 
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+#define THREAD_LOCAL_DECL __thread
+#endif
+
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_SPARCWORKS_HPP
--- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,4 +234,8 @@
 
 #define offset_of(klass,field) offsetof(klass,field)
 
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+#define THREAD_LOCAL_DECL __declspec( thread )
+#endif
+
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
--- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp	Fri Dec 04 04:06:37 2015 -0500
@@ -180,5 +180,8 @@
 #define SIZE_64G  ((uint64_t) UCONST64( 0x1000000000))
 #define SIZE_1T   ((uint64_t) UCONST64(0x10000000000))
 
+#ifndef USE_LIBRARY_BASED_TLS_ONLY
+#define THREAD_LOCAL_DECL __thread
+#endif
 
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Fri Dec 04 04:29:31 2015 +0000
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Fri Dec 04 04:06:37 2015 -0500
@@ -738,7 +738,7 @@
   }
 
 #ifdef ASSERT
-  Thread *thread = Thread::current();
+  Thread *thread = Thread::current_or_null();
   assert(thread == NULL ||
          (thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()),
          "Must be VMThread at safepoint");
@@ -1058,8 +1058,8 @@
       // bootstrap problem
       tty_lock == NULL ||
 
-      // can't grab a lock or call Thread::current() if TLS isn't initialized
-      ThreadLocalStorage::thread() == NULL ||
+      // can't grab a lock if current Thread isn't set
+      Thread::current_or_null() == NULL ||
 
       // developer hook
       !SerializeVMOutput ||