--- old/make/aix/makefiles/xlc.make 2015-11-04 23:02:14.591385472 -0500 +++ new/make/aix/makefiles/xlc.make 2015-11-04 23:02:12.743281320 -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 --- old/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2015-11-04 23:02:21.079751137 -0500 +++ new/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2015-11-04 23:02:18.955631429 -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" @@ -4649,3 +4650,24 @@ 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 Thread::current or, indeed, the call setup code. +// x86 appears to save C arg registers. + +void MacroAssembler::get_thread(Register dst) { + + // Save all call-clobbered regs except dst, plus r19 and r20. + RegSet saved_regs = RegSet::range(r0, r20) + lr - dst; + push(saved_regs, sp); + + // FIX-ME: implement + // return Thread::current() + + if (dst != c_rarg0) { + mov(dst, c_rarg0); + } + // restore pushed registers + pop(saved_regs, sp); +} --- old/src/cpu/sparc/vm/macroAssembler_sparc.cpp 2015-11-04 23:02:25.848019862 -0500 +++ new/src/cpu/sparc/vm/macroAssembler_sparc.cpp 2015-11-04 23:02:24.347935322 -0500 @@ -357,10 +357,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 @@ -390,7 +390,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; } --- old/src/cpu/sparc/vm/stubRoutines_sparc.cpp 2015-11-04 23:02:30.608288131 -0500 +++ new/src/cpu/sparc/vm/stubRoutines_sparc.cpp 2015-11-04 23:02:29.104203366 -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 @@ -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(); // Very early in process there is no thread. if (thread != NULL) { guarantee(thread->is_Java_thread(), "Not a Java thread."); --- old/src/cpu/x86/vm/macroAssembler_x86.cpp 2015-11-04 23:02:35.300552576 -0500 +++ new/src/cpu/x86/vm/macroAssembler_x86.cpp 2015-11-04 23:02:33.724463756 -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" @@ -9118,3 +9119,39 @@ 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); + LP64_ONLY(push(r8);) + LP64_ONLY(push(r9);) + LP64_ONLY(push(r10);) + LP64_ONLY(push(r11);) + + call(RuntimeAddress(CAST_FROM_FN_PTR(address, Thread::current))); + + LP64_ONLY(pop(r11);) + LP64_ONLY(pop(r10);) + LP64_ONLY(pop(r9);) + LP64_ONLY(pop(r8);) + pop(rcx); + pop(rdx); + LP64_ONLY(pop(rsi);) + LP64_ONLY(pop(rdi);) + if (thread != rax) { + mov(thread, rax); + pop(rax); + } +} + +#endif --- old/src/os/aix/vm/os_aix.cpp 2015-11-04 23:02:40.032819268 -0500 +++ new/src/os/aix/vm/os_aix.cpp 2015-11-04 23:02:38.532734730 -0500 @@ -914,7 +914,7 @@ int pid = os::current_process_id(); alloca(((pid ^ counter++) & 7) * 128); - ThreadLocalStorage::set_thread(thread); + thread->initialize_thread_current(); OSThread* osthread = thread->osthread(); @@ -1089,32 +1089,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 --- old/src/os/aix/vm/os_aix.inline.hpp 2015-11-04 23:02:44.785087091 -0500 +++ new/src/os/aix/vm/os_aix.inline.hpp 2015-11-04 23:02:43.204998042 -0500 @@ -36,10 +36,6 @@ #include #include -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); --- old/src/os/aix/vm/thread_aix.inline.hpp 2015-11-04 23:02:50.077385346 -0500 +++ new/src/os/aix/vm/thread_aix.inline.hpp 2015-11-04 23:02:47.897262482 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, 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. * @@ -26,11 +26,6 @@ #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 +// Nothing to do #endif // OS_AIX_VM_THREAD_AIX_INLINE_HPP --- old/src/os/bsd/vm/os_bsd.cpp 2015-11-04 23:02:55.517691942 -0500 +++ new/src/os/bsd/vm/os_bsd.cpp 2015-11-04 23:02:54.017607403 -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 --- old/src/os/bsd/vm/os_bsd.inline.hpp 2015-11-04 23:03:00.413967878 -0500 +++ new/src/os/bsd/vm/os_bsd.inline.hpp 2015-11-04 23:02:58.697871165 -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 #include -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); --- old/src/os/bsd/vm/thread_bsd.inline.hpp 2015-11-04 23:03:05.022227582 -0500 +++ new/src/os/bsd/vm/thread_bsd.inline.hpp 2015-11-04 23:03:03.526143268 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -29,11 +29,6 @@ #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 +// nothing to do #endif // OS_BSD_VM_THREAD_BSD_INLINE_HPP --- old/src/os/linux/vm/os_linux.cpp 2015-11-04 23:03:09.666489314 -0500 +++ new/src/os/linux/vm/os_linux.cpp 2015-11-04 23:03:08.134402972 -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. --- old/src/os/linux/vm/os_linux.inline.hpp 2015-11-04 23:03:14.366754202 -0500 +++ new/src/os/linux/vm/os_linux.inline.hpp 2015-11-04 23:03:12.862669438 -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 #include -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); --- old/src/os/linux/vm/thread_linux.inline.hpp 2015-11-04 23:03:19.059018640 -0500 +++ new/src/os/linux/vm/thread_linux.inline.hpp 2015-11-04 23:03:17.558934101 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -29,11 +29,6 @@ #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 +// nothing to do #endif // OS_LINUX_VM_THREAD_LINUX_INLINE_HPP --- old/src/os/solaris/vm/os_solaris.cpp 2015-11-04 23:03:23.819286909 -0500 +++ new/src/os/solaris/vm/os_solaris.cpp 2015-11-04 23:03:22.239197861 -0500 @@ -733,6 +733,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 @@ -5615,7 +5618,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(); if (t != NULL && t->is_inside_signal_handler()) { pid = fork(); } else { --- old/src/os/solaris/vm/thread_solaris.inline.hpp 2015-11-04 23:03:28.567554501 -0500 +++ new/src/os/solaris/vm/thread_solaris.inline.hpp 2015-11-04 23:03:27.067469963 -0500 @@ -29,22 +29,6 @@ #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; -} +// Nothing to do #endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP --- old/src/os/windows/vm/os_windows.cpp 2015-11-04 23:03:33.163813527 -0500 +++ new/src/os/windows/vm/os_windows.cpp 2015-11-04 23:03:31.671729440 -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"); @@ -2375,7 +2377,7 @@ address pc = (address) exceptionInfo->ContextRecord->Eip; #endif #endif - Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady + Thread* t = Thread::current(); // Handle SafeFetch32 and SafeFetchN exceptions. if (StubRoutines::is_safefetch_fault(pc)) { @@ -4002,27 +4004,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 @@ -4070,6 +4051,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 @@ -5282,7 +5266,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]; @@ -5992,3 +5976,16 @@ UseNUMAInterleaving = old_use_numa_interleaving; } #endif // PRODUCT + +// 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); +} --- old/src/os/windows/vm/os_windows.hpp 2015-11-04 23:03:37.876079090 -0500 +++ new/src/os/windows/vm/os_windows.hpp 2015-11-04 23:03:36.375994551 -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; } }; /* --- old/src/os/windows/vm/thread_windows.inline.hpp 2015-11-04 23:03:42.488339017 -0500 +++ new/src/os/windows/vm/thread_windows.inline.hpp 2015-11-04 23:03:40.992254706 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -29,11 +29,4 @@ #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 --- old/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp 2015-11-04 23:03:47.180603452 -0500 +++ new/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp 2015-11-04 23:03:45.680518911 -0500 @@ -167,7 +167,7 @@ ucontext_t* uc = (ucontext_t*) ucVoid; - Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady + Thread* t = Thread::current(); SignalHandlerMark shm(t); --- old/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp 2015-11-04 23:03:53.296948141 -0500 +++ new/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp 2015-11-04 23:03:50.976817389 -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 --- old/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2015-11-04 23:03:57.881206487 -0500 +++ new/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2015-11-04 23:03:56.389122401 -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(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp 2015-11-04 23:04:02.725479488 -0500 +++ new/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp 2015-11-04 23:04:01.221394726 -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 --- old/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2015-11-04 23:04:07.345739864 -0500 +++ new/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2015-11-04 23:04:05.841655101 -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(); SignalHandlerMark shm(t); --- old/src/os_cpu/linux_aarch64/vm/assembler_linux_aarch64.cpp 2015-11-04 23:04:11.966000239 -0500 +++ new/src/os_cpu/linux_aarch64/vm/assembler_linux_aarch64.cpp 2015-11-04 23:04:10.465915702 -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); -} - --- old/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp 2015-11-04 23:04:16.570259713 -0500 +++ new/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp 2015-11-04 23:04:15.078175627 -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(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp 2015-11-04 23:04:21.258523920 -0500 +++ new/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp 2015-11-04 23:04:19.762439608 -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(); SignalHandlerMark shm(t); --- old/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp 2015-11-04 23:04:26.038793312 -0500 +++ new/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp 2015-11-04 23:04:24.538708774 -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(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp 2015-11-04 23:04:30.659053686 -0500 +++ new/src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp 2015-11-04 23:04:29.162969374 -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 --- old/src/os_cpu/linux_x86/vm/os_linux_x86.cpp 2015-11-04 23:04:35.263313158 -0500 +++ new/src/os_cpu/linux_x86/vm/os_linux_x86.cpp 2015-11-04 23:04:33.763228621 -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(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp 2015-11-04 23:04:39.891573982 -0500 +++ new/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp 2015-11-04 23:04:38.391489445 -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 --- old/src/os_cpu/linux_zero/vm/os_linux_zero.cpp 2015-11-04 23:04:44.491833228 -0500 +++ new/src/os_cpu/linux_zero/vm/os_linux_zero.cpp 2015-11-04 23:04:42.999749142 -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(); SignalHandlerMark shm(t); --- old/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp 2015-11-04 23:04:49.184097658 -0500 +++ new/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp 2015-11-04 23:04:47.684013122 -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(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp 2015-11-04 23:04:55.308442793 -0500 +++ new/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp 2015-11-04 23:04:53.808358259 -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); - } -} --- old/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp 2015-11-04 23:04:59.904701812 -0500 +++ new/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp 2015-11-04 23:04:58.408617499 -0500 @@ -346,7 +346,7 @@ } #endif // !AMD64 - Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady + Thread* t = Thread::current(); // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away // (no destructors can be run) --- old/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp 2015-11-04 23:05:04.744974582 -0500 +++ new/src/os_cpu/windows_x86/vm/assembler_windows_x86.cpp 2015-11-04 23:05:03.244890046 -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())); -} -#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)); - - 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); - } + movl(thread, Address(thread, os::win32::get_thread_ptr_offset())); } + +// #else - use shared x86 implementation in cpu/x86/vm/macroAssembler_x86.cpp + #endif --- old/src/os_cpu/windows_x86/vm/os_windows_x86.cpp 2015-11-04 23:05:09.349234051 -0500 +++ new/src/os_cpu/windows_x86/vm/os_windows_x86.cpp 2015-11-04 23:05:07.853149741 -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 --- old/src/share/vm/code/nmethod.cpp 2015-11-04 23:05:13.973494648 -0500 +++ new/src/share/vm/code/nmethod.cpp 2015-11-04 23:05:12.469409887 -0500 @@ -2662,7 +2662,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); --- old/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp 2015-11-04 23:05:18.721762232 -0500 +++ new/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp 2015-11-04 23:05:17.137672962 -0500 @@ -144,9 +144,6 @@ _cmst = NULL; Terminator_lock->notify(); } - - // Thread destructor usually does this.. - ThreadLocalStorage::set_thread(NULL); } #ifndef PRODUCT --- old/src/share/vm/gc/g1/g1HotCardCache.hpp 2015-11-04 23:05:23.390025307 -0500 +++ new/src/share/vm/gc/g1/g1HotCardCache.hpp 2015-11-04 23:05:21.809936263 -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(); } --- old/src/share/vm/gc/parallel/gcTaskThread.cpp 2015-11-04 23:05:28.078289510 -0500 +++ new/src/share/vm/gc/parallel/gcTaskThread.cpp 2015-11-04 23:05:26.582205199 -0500 @@ -96,7 +96,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()) { --- old/src/share/vm/gc/shared/concurrentGCThread.cpp 2015-11-04 23:05:32.706550330 -0500 +++ new/src/share/vm/gc/shared/concurrentGCThread.cpp 2015-11-04 23:05:31.206465795 -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) { --- old/src/share/vm/gc/shared/workgroup.cpp 2015-11-04 23:05:37.326810699 -0500 +++ new/src/share/vm/gc/shared/workgroup.cpp 2015-11-04 23:05:35.822725939 -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"); --- old/src/share/vm/memory/allocation.cpp 2015-11-04 23:05:41.947071069 -0500 +++ new/src/share/vm/memory/allocation.cpp 2015-11-04 23:05:40.442986308 -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 } --- old/src/share/vm/memory/resourceArea.hpp 2015-11-04 23:05:46.651336171 -0500 +++ new/src/share/vm/memory/resourceArea.hpp 2015-11-04 23:05:45.071247127 -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(); --- old/src/share/vm/oops/oopsHierarchy.cpp 2015-11-04 23:05:51.955635087 -0500 +++ new/src/share/vm/oops/oopsHierarchy.cpp 2015-11-04 23:05:49.763511553 -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); } --- old/src/share/vm/precompiled/precompiled.hpp 2015-11-04 23:05:57.379940766 -0500 +++ new/src/share/vm/precompiled/precompiled.hpp 2015-11-04 23:05:55.883856457 -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" --- old/src/share/vm/prims/jni.cpp 2015-11-04 23:06:02.204212631 -0500 +++ new/src/share/vm/prims/jni.cpp 2015-11-04 23:06:00.484115697 -0500 @@ -4154,7 +4154,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(); @@ -4169,10 +4169,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; @@ -4279,8 +4277,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 operations is a no-op + if (Thread::current_or_null() == NULL) { HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK); return JNI_OK; } @@ -4337,7 +4335,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(); --- old/src/share/vm/prims/jniCheck.cpp 2015-11-04 23:06:06.892476831 -0500 +++ new/src/share/vm/prims/jniCheck.cpp 2015-11-04 23:06:05.392392295 -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(); \ --- old/src/share/vm/prims/jvmtiEnter.xsl 2015-11-04 23:06:11.536738547 -0500 +++ new/src/share/vm/prims/jvmtiEnter.xsl 2015-11-04 23:06:10.036654012 -0500 @@ -494,7 +494,7 @@ } - Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); + Thread* this_thread = Thread::current_or_null(); @@ -528,7 +528,7 @@ return JVMTI_ERROR_WRONG_PHASE; } - Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); + Thread* this_thread = Thread::current_or_null(); @@ -558,7 +558,7 @@ if (Threads::number_of_threads() != 0) { - Thread* this_thread = (Thread*)ThreadLocalStorage::thread(); + Thread* this_thread = Thread::current_or_null(); @@ -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) && !this_thread->is_VM_thread() && !this_thread->is_ConcurrentGC_thread()); } if (transition) { --- old/src/share/vm/prims/jvmtiExport.cpp 2015-11-04 23:06:16.193000945 -0500 +++ new/src/share/vm/prims/jvmtiExport.cpp 2015-11-04 23:06:14.660914607 -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(); --- old/src/share/vm/prims/jvmtiUtil.hpp 2015-11-04 23:06:20.941268524 -0500 +++ new/src/share/vm/prims/jvmtiUtil.hpp 2015-11-04 23:06:19.441183990 -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(); } --- old/src/share/vm/runtime/interfaceSupport.cpp 2015-11-04 23:06:25.701536780 -0500 +++ new/src/share/vm/runtime/interfaceSupport.cpp 2015-11-04 23:06:24.125447962 -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" --- old/src/share/vm/runtime/interfaceSupport.hpp 2015-11-04 23:06:30.309796469 -0500 +++ new/src/share/vm/runtime/interfaceSupport.hpp 2015-11-04 23:06:28.805711710 -0500 @@ -567,7 +567,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) --- old/src/share/vm/runtime/java.cpp 2015-11-04 23:06:34.926056609 -0500 +++ new/src/share/vm/runtime/java.cpp 2015-11-04 23:06:33.425972075 -0500 @@ -511,8 +511,7 @@ } void vm_exit(int code) { - Thread* thread = ThreadLocalStorage::is_initialized() ? - ThreadLocalStorage::get_thread_slow() : NULL; + Thread* thread = Thread::current_or_null(); if (thread == NULL) { // we have serious problems -- just exit vm_direct_exit(code); @@ -550,8 +549,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) @@ -605,7 +603,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_or_null(); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; } --- old/src/share/vm/runtime/mutex.cpp 2015-11-04 23:06:39.534316298 -0500 +++ new/src/share/vm/runtime/mutex.cpp 2015-11-04 23:06:38.034231763 -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; } --- old/src/share/vm/runtime/mutexLocker.cpp 2015-11-04 23:06:44.170577564 -0500 +++ new/src/share/vm/runtime/mutexLocker.cpp 2015-11-04 23:06:42.658492354 -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): --- old/src/share/vm/runtime/os.cpp 2015-11-04 23:06:48.850841309 -0500 +++ new/src/share/vm/runtime/os.cpp 2015-11-04 23:06:47.354757001 -0500 @@ -419,28 +419,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; } @@ -573,7 +551,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"); --- old/src/share/vm/runtime/os.hpp 2015-11-04 23:06:54.991187334 -0500 +++ new/src/share/vm/runtime/os.hpp 2015-11-04 23:06:52.667056364 -0500 @@ -663,12 +663,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. --- old/src/share/vm/runtime/sharedRuntime.hpp 2015-11-04 23:06:59.611447698 -0500 +++ new/src/share/vm/runtime/sharedRuntime.hpp 2015-11-04 23:06:58.111363164 -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" --- old/src/share/vm/runtime/thread.cpp 2015-11-04 23:07:04.439719783 -0500 +++ new/src/share/vm/runtime/thread.cpp 2015-11-04 23:07:02.947635700 -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,8 @@ #endif // ndef DTRACE_ENABLED +// Current thread is maintained as a thread-local variable +THREAD_LOCAL_DECL Thread* Thread::_thr_current = NULL; // Class hierarchy // - Thread @@ -281,22 +282,13 @@ #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_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. +void Thread::initialize_thread_current() { + assert(_thr_current == NULL, "Thread::current already initialized"); + _thr_current = this; +} - // initialize structure dependent on thread local storage - ThreadLocalStorage::set_thread(this); +void Thread::clear_thread_current() { + _thr_current = NULL; } void Thread::record_stack_base_and_size() { @@ -364,15 +356,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 +1262,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 +1314,6 @@ _watcher_thread = NULL; Terminator_lock->notify(); } - - // Thread destructor usually does this.. - ThreadLocalStorage::set_thread(NULL); } void WatcherThread::start() { @@ -1663,9 +1648,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,7 +1979,7 @@ JavaThread* JavaThread::active() { - Thread* thread = ThreadLocalStorage::thread(); + Thread* thread = Thread::current(); assert(thread != NULL, "just checking"); if (thread->is_Java_thread()) { return (JavaThread*) thread; @@ -3412,9 +3394,6 @@ jint adjust_after_os_result = Arguments::adjust_after_os(); if (adjust_after_os_result != JNI_OK) return adjust_after_os_result; - // initialize TLS - ThreadLocalStorage::init(); - // Initialize output stream logging ostream_init_log(); @@ -3449,14 +3428,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()) { --- old/src/share/vm/runtime/thread.hpp 2015-11-04 23:07:09.151985331 -0500 +++ new/src/share/vm/runtime/thread.hpp 2015-11-04 23:07:07.651900797 -0500 @@ -39,7 +39,6 @@ #include "runtime/park.hpp" #include "runtime/safepoint.hpp" #include "runtime/stubRoutines.hpp" -#include "runtime/threadLocalStorage.hpp" #include "runtime/thread_ext.hpp" #include "runtime/unhandledOops.hpp" #include "trace/traceBackend.hpp" @@ -102,6 +101,9 @@ class Thread: public ThreadShadow { friend class VMStructs; private: + // Current thread is maintained as a thread-local variable + static THREAD_LOCAL_DECL Thread* _thr_current; + // Exception handling // (Note: _pending_exception and friends are in ThreadShadow) //oop _pending_exception; // pending exception for current thread @@ -260,7 +262,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 +308,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 +341,10 @@ 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(); // Common thread operations static void set_priority(Thread* thread, ThreadPriority priority); @@ -649,25 +653,13 @@ }; // 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_.inline.hpp. - 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"); -#endif -#endif - Thread* thread = ThreadLocalStorage::thread(); - assert(thread != NULL, "just checking"); - return thread; + assert(_thr_current != NULL, "Thread::current() called on detached thread"); + return _thr_current; +} + +inline Thread* Thread::current_or_null() { + return _thr_current; } // Name support for threads. non-JavaThread subclasses with multiple @@ -1842,7 +1834,7 @@ // Inline implementation of JavaThread::current inline JavaThread* JavaThread::current() { - Thread* thread = ThreadLocalStorage::thread(); + Thread* thread = Thread::current(); assert(thread != NULL && thread->is_Java_thread(), "just checking"); return (JavaThread*)thread; } --- old/src/share/vm/runtime/vmThread.cpp 2015-11-04 23:07:13.796247049 -0500 +++ new/src/share/vm/runtime/vmThread.cpp 2015-11-04 23:07:12.304162965 -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. --- old/src/share/vm/runtime/vm_operations.cpp 2015-11-04 23:07:18.408506956 -0500 +++ new/src/share/vm/runtime/vm_operations.cpp 2015-11-04 23:07:16.912422648 -0500 @@ -372,7 +372,7 @@ int VM_Exit::set_vm_exited() { CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::LastStep); - Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); + Thread * thr_cur = Thread::current_or_null(); assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); @@ -394,7 +394,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); @@ -471,7 +471,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(); --- old/src/share/vm/utilities/debug.cpp 2015-11-04 23:07:23.116772278 -0500 +++ new/src/share/vm/utilities/debug.cpp 2015-11-04 23:07:21.612687520 -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 @@ -534,7 +534,7 @@ #endif // !PRODUCT extern "C" void ps() { // print stack - if (Thread::current() == NULL) return; + if (Thread::current_or_null() == NULL) return; Command c("ps"); @@ -613,7 +613,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)); } @@ -770,7 +770,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)); --- old/src/share/vm/utilities/events.cpp 2015-11-04 23:07:27.881040755 -0500 +++ new/src/share/vm/utilities/events.cpp 2015-11-04 23:07:26.380956223 -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" --- old/src/share/vm/utilities/events.hpp 2015-11-04 23:07:32.485300214 -0500 +++ new/src/share/vm/utilities/events.hpp 2015-11-04 23:07:30.985215682 -0500 @@ -248,8 +248,8 @@ template inline void EventLogBase::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); --- old/src/share/vm/utilities/globalDefinitions_gcc.hpp 2015-11-04 23:07:37.105560575 -0500 +++ new/src/share/vm/utilities/globalDefinitions_gcc.hpp 2015-11-04 23:07:35.597475591 -0500 @@ -326,4 +326,6 @@ #define JLONG_FORMAT "%ld" #endif // _LP64 && __APPLE__ +#define THREAD_LOCAL_DECL __thread + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP --- old/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2015-11-04 23:07:42.321854523 -0500 +++ new/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2015-11-04 23:07:40.829770441 -0500 @@ -273,4 +273,6 @@ #define offset_of(klass,field) offsetof(klass,field) +#define THREAD_LOCAL_DECL __thread + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_SPARCWORKS_HPP --- old/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2015-11-04 23:07:47.006118490 -0500 +++ new/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2015-11-04 23:07:45.430029675 -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 @@ -232,4 +232,6 @@ #define offset_of(klass,field) offsetof(klass,field) +#define THREAD_LOCAL_DECL __declspec( thread ) + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP --- old/src/share/vm/utilities/globalDefinitions_xlc.hpp 2015-11-04 23:07:51.602377498 -0500 +++ new/src/share/vm/utilities/globalDefinitions_xlc.hpp 2015-11-04 23:07:50.102292965 -0500 @@ -180,5 +180,6 @@ #define SIZE_64G ((uint64_t) UCONST64( 0x1000000000)) #define SIZE_1T ((uint64_t) UCONST64(0x10000000000)) +#define THREAD_LOCAL_DECL __thread #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP --- old/src/share/vm/utilities/ostream.cpp 2015-11-04 23:07:57.682720135 -0500 +++ new/src/share/vm/utilities/ostream.cpp 2015-11-04 23:07:56.186635829 -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 || --- old/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.cpp 2015-11-04 23:08:02.282979368 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp 2015-11-04 23:08:05.531162407 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp 2015-11-04 23:08:08.559333049 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 -} --- old/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp 2015-11-04 23:08:11.599504368 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp 2015-11-04 23:08:14.631675235 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp 2015-11-04 23:08:17.651845426 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.cpp 2015-11-04 23:08:20.764020801 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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; -} --- old/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.hpp 2015-11-04 23:08:23.804192119 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.cpp 2015-11-04 23:08:27.012372904 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/linux_ppc/vm/threadLS_linux_ppc.hpp 2015-11-04 23:08:30.044543768 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp 2015-11-04 23:08:33.072714412 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.hpp 2015-11-04 23:08:36.104885278 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp 2015-11-04 23:08:39.137056142 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_x86/vm/threadLS_linux_x86.hpp 2015-11-04 23:08:42.169227009 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp 2015-11-04 23:08:45.193397424 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp 2015-11-04 23:08:48.313573249 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp 2015-11-04 23:08:51.345744114 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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(); -} --- old/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp 2015-11-04 23:08:55.145958260 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp 2015-11-04 23:08:58.934171728 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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(); -} --- old/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp 2015-11-04 23:09:01.966342593 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp 2015-11-04 23:09:05.514542537 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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); -} --- old/src/os_cpu/windows_x86/vm/threadLS_windows_x86.hpp 2015-11-04 23:09:08.546713402 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/share/vm/runtime/threadLocalStorage.cpp 2015-11-04 23:09:11.578884266 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -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 --- old/src/share/vm/runtime/threadLocalStorage.hpp 2015-11-04 23:09:14.607054905 -0500 +++ /dev/null 2015-09-28 11:47:54.419050997 -0400 @@ -1,110 +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. - * - */ - -#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 - -// 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(); - -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 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(); - -}; - -#endif // SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP