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 = &registers;
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block    void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 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)&regs, &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, &regs);
36965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return sizeof(CONTEXT);
37081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(PTHREADS)
37181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    pthread_attr_init(&regs);
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, &regs);
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, &regs);
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(&regs, &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(&regs);
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*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + 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