165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/* 265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2009 Acision BV. All rights reserved. 565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * This library is free software; you can redistribute it and/or 765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modify it under the terms of the GNU Lesser General Public 865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * License as published by the Free Software Foundation; either 965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * version 2 of the License, or (at your option) any later version. 1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * This library is distributed in the hope that it will be useful, 1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of 1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Lesser General Public License for more details. 1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * You should have received a copy of the GNU Lesser General Public 1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * License along with this library; if not, write to the Free Software 1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */ 2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "config.h" 2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "MachineStackMarker.h" 2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "ConservativeRoots.h" 2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Heap.h" 2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "JSArray.h" 2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "JSGlobalData.h" 2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <setjmp.h> 3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <stdlib.h> 312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/StdLibExtras.h> 322bde8e466a4451c7319e3a072d118917957d6554Steve Block 332bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(PTHREAD_BASED_QT) && !defined(WTF_USE_PTHREADS) 342bde8e466a4451c7319e3a072d118917957d6554Steve Block#define WTF_USE_PTHREADS 1 352bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <mach/mach_init.h> 4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <mach/mach_port.h> 4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <mach/task.h> 4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <mach/thread_act.h> 4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <mach/vm_map.h> 4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <windows.h> 4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <malloc.h> 4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(HAIKU) 5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <OS.h> 5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(UNIX) 5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <stdlib.h> 5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if !OS(HAIKU) 5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <sys/mman.h> 5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <unistd.h> 6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(SOLARIS) 6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <thread.h> 6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <pthread.h> 6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if HAVE(PTHREAD_NP_H) 6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <pthread_np.h> 7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(QNX) 7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <fcntl.h> 7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <sys/procfs.h> 7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <stdio.h> 7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <errno.h> 7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) 8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <signal.h> 8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#ifndef SA_RESTART 822bde8e466a4451c7319e3a072d118917957d6554Steve Block#error MachineThreads requires SA_RESTART 8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 882bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing namespace WTF; 892bde8e466a4451c7319e3a072d118917957d6554Steve Block 9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace JSC { 9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 922fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic inline void swapIfBackwards(void*& begin, void*& end) 932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if OS(WINCE) 952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (begin <= end) 962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return; 972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block std::swap(begin, end); 982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#else 992fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockUNUSED_PARAM(begin); 1002fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockUNUSED_PARAM(end); 1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif 1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef mach_port_t PlatformThread; 10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef HANDLE PlatformThread; 11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtypedef pthread_t PlatformThread; 11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic const int SigThreadSuspendResume = SIGUSR2; 11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void pthreadSignalHandlerSuspendResume(int signo) 11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigset_t signalSet; 11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigemptyset(&signalSet); 11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigaddset(&signalSet, SigThreadSuspendResume); 11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigsuspend(&signalSet); 12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1232bde8e466a4451c7319e3a072d118917957d6554Steve Blockclass MachineThreads::Thread { 12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochpublic: 12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread(pthread_t pthread, const PlatformThread& platThread, void* base) 12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch : posixThread(pthread) 12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , platformThread(platThread) 12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , stackBase(base) 12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch { 13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) 13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch struct sigaction action; 13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch action.sa_handler = pthreadSignalHandlerSuspendResume; 13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigemptyset(&action.sa_mask); 13481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch action.sa_flags = SA_RESTART; 13581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigaction(SigThreadSuspendResume, &action, 0); 13681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 13781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigset_t mask; 13881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigemptyset(&mask); 13981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch sigaddset(&mask, SigThreadSuspendResume); 14081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_sigmask(SIG_UNBLOCK, &mask, 0); 14181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* next; 14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pthread_t posixThread; 14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PlatformThread platformThread; 14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void* stackBase; 14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1522bde8e466a4451c7319e3a072d118917957d6554Steve BlockMachineThreads::MachineThreads(Heap* heap) 15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch : m_heap(heap) 15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_registeredThreads(0) 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block , m_threadSpecific(0) 15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1612bde8e466a4451c7319e3a072d118917957d6554Steve BlockMachineThreads::~MachineThreads() 16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 1642bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_threadSpecific) { 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block int error = pthread_key_delete(m_threadSpecific); 16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT_UNUSED(error, !error); 16765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 16865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 16965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MutexLocker registeredThreadsLock(m_registeredThreadsMutex); 17065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (Thread* t = m_registeredThreads; t;) { 17165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* next = t->next; 17265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch delete t; 17365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch t = next; 17465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic inline PlatformThread getCurrentPlatformThread() 18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return pthread_mach_thread_np(pthread_self()); 18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return pthread_getw32threadhandle_np(pthread_self()); 18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 18781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return pthread_self(); 18865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1912bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::makeUsableFromMultipleThreads() 19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 1932bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_threadSpecific) 19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 19565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 1962bde8e466a4451c7319e3a072d118917957d6554Steve Block int error = pthread_key_create(&m_threadSpecific, removeThread); 19765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (error) 19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CRASH(); 19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2012bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::addCurrentThread() 20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread()); 20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2052bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!m_threadSpecific || pthread_getspecific(m_threadSpecific)) 20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2082bde8e466a4451c7319e3a072d118917957d6554Steve Block pthread_setspecific(m_threadSpecific, this); 20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* thread = new Thread(pthread_self(), getCurrentPlatformThread(), m_heap->globalData()->stack().origin()); 21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MutexLocker lock(m_registeredThreadsMutex); 21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread->next = m_registeredThreads; 21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_registeredThreads = thread; 21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2172bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::removeThread(void* p) 21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (p) 2202bde8e466a4451c7319e3a072d118917957d6554Steve Block static_cast<MachineThreads*>(p)->removeCurrentThread(); 22165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2232bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::removeCurrentThread() 22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pthread_t currentPosixThread = pthread_self(); 22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MutexLocker lock(m_registeredThreadsMutex); 22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) { 23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* t = m_registeredThreads; 23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_registeredThreads = m_registeredThreads->next; 23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch delete t; 23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } else { 23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* last = m_registeredThreads; 23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Thread* t; 23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (t = m_registeredThreads->next; t; t = t->next) { 23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (pthread_equal(t->posixThread, currentPosixThread)) { 23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch last->next = t->next; 23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch break; 24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch last = t; 24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(t); // If t is NULL, we never found ourselves in the list. 24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch delete t; 24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if COMPILER(GCC) 25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*)))) 25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#define REGISTER_BUFFER_ALIGNMENT 25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2562bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, void* stackCurrent) 25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // setjmp forces volatile registers onto the stack 25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch jmp_buf registers REGISTER_BUFFER_ALIGNMENT; 26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if COMPILER(MSVC) 26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#pragma warning(push) 26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#pragma warning(disable: 4611) 26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch setjmp(registers); 26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if COMPILER(MSVC) 26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#pragma warning(pop) 26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 2692bde8e466a4451c7319e3a072d118917957d6554Steve Block void* registersBegin = ®isters; 2702bde8e466a4451c7319e3a072d118917957d6554Steve Block void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(®isters + 1))); 2712bde8e466a4451c7319e3a072d118917957d6554Steve Block swapIfBackwards(registersBegin, registersEnd); 2722bde8e466a4451c7319e3a072d118917957d6554Steve Block conservativeRoots.add(registersBegin, registersEnd); 2732bde8e466a4451c7319e3a072d118917957d6554Steve Block 2742bde8e466a4451c7319e3a072d118917957d6554Steve Block void* stackBegin = stackCurrent; 2752bde8e466a4451c7319e3a072d118917957d6554Steve Block void* stackEnd = m_heap->globalData()->stack().origin(); 2762bde8e466a4451c7319e3a072d118917957d6554Steve Block swapIfBackwards(stackBegin, stackEnd); 2772bde8e466a4451c7319e3a072d118917957d6554Steve Block conservativeRoots.add(stackBegin, stackEnd); 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic inline void suspendThread(const PlatformThread& platformThread) 28365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_suspend(platformThread); 28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SuspendThread(platformThread); 28881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 28981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_kill(platformThread, SigThreadSuspendResume); 29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to suspend threads on this platform 29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic inline void resumeThread(const PlatformThread& platformThread) 29665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_resume(platformThread); 29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) 30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ResumeThread(platformThread); 30181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 30281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_kill(platformThread, SigThreadSuspendResume); 30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to resume threads on this platform 30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit 30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if CPU(X86) 31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef i386_thread_state_t PlatformThreadRegisters; 31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86_64) 31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef x86_thread_state64_t PlatformThreadRegisters; 31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC) 31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef ppc_thread_state_t PlatformThreadRegisters; 31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC64) 31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef ppc_thread_state64_t PlatformThreadRegisters; 32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(ARM) 32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef arm_thread_state_t PlatformThreadRegisters; 32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Unknown Architecture 32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) && CPU(X86) 32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtypedef CONTEXT PlatformThreadRegisters; 32881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 32981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtypedef pthread_attr_t PlatformThreadRegisters; 33065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 33165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a thread register struct for this platform 33265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 33365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs) 33565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 33665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 33765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if CPU(X86) 33965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned user_count = sizeof(regs)/sizeof(int); 34065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_state_flavor_t flavor = i386_THREAD_STATE; 34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86_64) 34265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned user_count = x86_THREAD_STATE64_COUNT; 34365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_state_flavor_t flavor = x86_THREAD_STATE64; 34465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC) 34565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned user_count = PPC_THREAD_STATE_COUNT; 34665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_state_flavor_t flavor = PPC_THREAD_STATE; 34765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC64) 34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned user_count = PPC_THREAD_STATE64_COUNT; 34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_state_flavor_t flavor = PPC_THREAD_STATE64; 35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(ARM) 35165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned user_count = ARM_THREAD_STATE_COUNT; 35265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch thread_state_flavor_t flavor = ARM_THREAD_STATE; 35365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 35465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Unknown Architecture 35565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 35665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 35765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)®s, &user_count); 35865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (result != KERN_SUCCESS) { 35965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 36065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result); 36165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CRASH(); 36265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 36365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return user_count * sizeof(usword_t); 36465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// end OS(DARWIN) 36565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 36665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif OS(WINDOWS) && CPU(X86) 36765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS; 36865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch GetThreadContext(platformThread, ®s); 36965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return sizeof(CONTEXT); 37081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 37181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_attr_init(®s); 37281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if HAVE(PTHREAD_NP_H) || OS(NETBSD) 37381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // e.g. on FreeBSD 5.4, neundorf@kde.org 37481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_attr_get_np(platformThread, ®s); 37581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#else 37681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // FIXME: this function is non-portable; other POSIX systems may have different np alternatives 37781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_getattr_np(platformThread, ®s); 37881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 37981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return 0; 38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 38165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to get thread registers on this platform 38265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 38365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 38465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) 38665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 38765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if OS(DARWIN) 38865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if __DARWIN_UNIX03 39065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 39165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if CPU(X86) 39265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.__esp); 39365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86_64) 39465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.__rsp); 39565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC) || CPU(PPC64) 39665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.__r1); 39765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(ARM) 39865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.__sp); 39965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 40065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Unknown Architecture 40165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 40265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 40365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else // !__DARWIN_UNIX03 40465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 40565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if CPU(X86) 40665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.esp); 40765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86_64) 40865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.rsp); 40965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(PPC) || CPU(PPC64) 41065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>(regs.r1); 41165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 41265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Unknown Architecture 41365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 41465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 41565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif // __DARWIN_UNIX03 41665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 41765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// end OS(DARWIN) 41865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif CPU(X86) && OS(WINDOWS) 41965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return reinterpret_cast<void*>((uintptr_t) regs.Esp); 42081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS) 42181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch void* stackBase = 0; 42281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch size_t stackSize = 0; 42381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch int rc = pthread_attr_getstack(®s, &stackBase, &stackSize); 42481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch (void)rc; // FIXME: Deal with error code somehow? Seems fatal. 42581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(stackBase); 42681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return static_cast<char*>(stackBase) + stackSize; 42765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 42865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error Need a way to get the stack pointer for another thread on this platform 42965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 43065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 43165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 43281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic void freePlatformThreadRegisters(PlatformThreadRegisters& regs) 43381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{ 43481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) 43581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch pthread_attr_destroy(®s); 43681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#else 43781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch UNUSED_PARAM(regs); 43881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif 43981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} 44081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 4412bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread) 44265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 44365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch suspendThread(thread->platformThread); 44465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 44565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PlatformThreadRegisters regs; 44665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs); 44765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4482bde8e466a4451c7319e3a072d118917957d6554Steve Block conservativeRoots.add(static_cast<void*>(®s), static_cast<void*>(reinterpret_cast<char*>(®s) + regSize)); 44965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 45065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch void* stackPointer = otherThreadStackPointer(regs); 4512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block void* stackBase = thread->stackBase; 4522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block swapIfBackwards(stackPointer, stackBase); 4532bde8e466a4451c7319e3a072d118917957d6554Steve Block conservativeRoots.add(stackPointer, stackBase); 45465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 45565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch resumeThread(thread->platformThread); 45681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 45781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch freePlatformThreadRegisters(regs); 45865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 45965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 46065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 46165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4622bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, void* stackCurrent) 46365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 4642bde8e466a4451c7319e3a072d118917957d6554Steve Block gatherFromCurrentThread(conservativeRoots, stackCurrent); 46565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 46665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(JSC_MULTIPLE_THREADS) 46765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4682bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_threadSpecific) { 46965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 47065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MutexLocker lock(m_registeredThreadsMutex); 47165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 47265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifndef NDEBUG 4732bde8e466a4451c7319e3a072d118917957d6554Steve Block // Forbid malloc during the gather phase. The gather phase suspends 4742bde8e466a4451c7319e3a072d118917957d6554Steve Block // threads, so a malloc during gather would risk a deadlock with a 4752bde8e466a4451c7319e3a072d118917957d6554Steve Block // thread that had been suspended while holding the malloc lock. 47665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch fastMallocForbid(); 47765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 47865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held, 47965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // and since this is a shared heap, they are real locks. 48065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (Thread* thread = m_registeredThreads; thread; thread = thread->next) { 48165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!pthread_equal(thread->posixThread, pthread_self())) 4822bde8e466a4451c7319e3a072d118917957d6554Steve Block gatherFromOtherThread(conservativeRoots, thread); 48365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 48465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifndef NDEBUG 48565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch fastMallocAllow(); 48665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 48765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 48865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 48965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 49065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 49165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace JSC 492