Changeset 184218 in webkit


Ignore:
Timestamp:
May 12, 2015, 2:20:26 PM (10 years ago)
Author:
mark.lam@apple.com
Message:

Refactor MachineStackMarker.cpp so that it's easier to reason about MachineThreads::Thread.
https://bugs.webkit.org/show_bug.cgi?id=144925

Reviewed by Michael Saboff.

Currently, the code in MachineStackMarker.cpp is written as a bunch of functions that
operate on the platformThread value in the MachineThreads::Thread struct. Instead, we
can apply better OO encapsulation and convert all these functions into methods of the
MachineThreads::Thread struct.

This will also make it easier to reason about the fix for
https://bugs.webkit.org/show_bug.cgi?id=144924 later.

  • heap/MachineStackMarker.cpp:

(JSC::getCurrentPlatformThread):
(JSC::MachineThreads::Thread::createForCurrentThread):
(JSC::MachineThreads::Thread::operator!=):
(JSC::MachineThreads::Thread::operator==):
(JSC::MachineThreads::addCurrentThread):
(JSC::MachineThreads::removeThreadIfFound):
(JSC::MachineThreads::Thread::suspend):
(JSC::MachineThreads::Thread::resume):
(JSC::MachineThreads::Thread::getRegisters):
(JSC::MachineThreads::Thread::Registers::stackPointer):
(JSC::MachineThreads::Thread::freeRegisters):
(JSC::MachineThreads::Thread::captureStack):
(JSC::MachineThreads::tryCopyOtherThreadStack):
(JSC::MachineThreads::tryCopyOtherThreadStacks):
(JSC::equalThread): Deleted.
(JSC::suspendThread): Deleted.
(JSC::resumeThread): Deleted.
(JSC::getPlatformThreadRegisters): Deleted.
(JSC::otherThreadStackPointer): Deleted.
(JSC::freePlatformThreadRegisters): Deleted.
(JSC::otherThreadStack): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r184217 r184218  
     12015-05-12  Mark Lam  <mark.lam@apple.com>
     2
     3        Refactor MachineStackMarker.cpp so that it's easier to reason about MachineThreads::Thread.
     4        https://bugs.webkit.org/show_bug.cgi?id=144925
     5
     6        Reviewed by Michael Saboff.
     7
     8        Currently, the code in MachineStackMarker.cpp is written as a bunch of functions that
     9        operate on the platformThread value in the MachineThreads::Thread struct.  Instead, we
     10        can apply better OO encapsulation and convert all these functions into methods of the
     11        MachineThreads::Thread struct.
     12
     13        This will also make it easier to reason about the fix for
     14        https://bugs.webkit.org/show_bug.cgi?id=144924 later.
     15
     16        * heap/MachineStackMarker.cpp:
     17        (JSC::getCurrentPlatformThread):
     18        (JSC::MachineThreads::Thread::createForCurrentThread):
     19        (JSC::MachineThreads::Thread::operator!=):
     20        (JSC::MachineThreads::Thread::operator==):
     21        (JSC::MachineThreads::addCurrentThread):
     22        (JSC::MachineThreads::removeThreadIfFound):
     23        (JSC::MachineThreads::Thread::suspend):
     24        (JSC::MachineThreads::Thread::resume):
     25        (JSC::MachineThreads::Thread::getRegisters):
     26        (JSC::MachineThreads::Thread::Registers::stackPointer):
     27        (JSC::MachineThreads::Thread::freeRegisters):
     28        (JSC::MachineThreads::Thread::captureStack):
     29        (JSC::MachineThreads::tryCopyOtherThreadStack):
     30        (JSC::MachineThreads::tryCopyOtherThreadStacks):
     31        (JSC::equalThread): Deleted.
     32        (JSC::suspendThread): Deleted.
     33        (JSC::resumeThread): Deleted.
     34        (JSC::getPlatformThreadRegisters): Deleted.
     35        (JSC::otherThreadStackPointer): Deleted.
     36        (JSC::freePlatformThreadRegisters): Deleted.
     37        (JSC::otherThreadStack): Deleted.
     38
    1392015-05-12  Ryosuke Niwa  <rniwa@webkit.org>
    240
  • trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp

    r181060 r184218  
    147147}
    148148   
     149static inline PlatformThread getCurrentPlatformThread()
     150{
     151#if OS(DARWIN)
     152    return pthread_mach_thread_np(pthread_self());
     153#elif OS(WINDOWS)
     154    return GetCurrentThread();
     155#elif USE(PTHREADS)
     156    return pthread_self();
     157#endif
     158}
    149159
    150160class MachineThreads::Thread {
    151161    WTF_MAKE_FAST_ALLOCATED;
    152 public:
     162
    153163    Thread(const PlatformThread& platThread, void* base)
    154164        : platformThread(platThread)
     
    170180    }
    171181
     182public:
     183    static Thread* createForCurrentThread()
     184    {
     185        return new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
     186    }
     187
     188    struct Registers {
     189        inline void* stackPointer() const;
     190       
     191#if OS(DARWIN)
     192#if CPU(X86)
     193        typedef i386_thread_state_t PlatformRegisters;
     194#elif CPU(X86_64)
     195        typedef x86_thread_state64_t PlatformRegisters;
     196#elif CPU(PPC)
     197        typedef ppc_thread_state_t PlatformRegisters;
     198#elif CPU(PPC64)
     199        typedef ppc_thread_state64_t PlatformRegisters;
     200#elif CPU(ARM)
     201        typedef arm_thread_state_t PlatformRegisters;
     202#elif CPU(ARM64)
     203        typedef arm_thread_state64_t PlatformRegisters;
     204#else
     205#error Unknown Architecture
     206#endif
     207       
     208#elif OS(WINDOWS)
     209        typedef CONTEXT PlatformRegisters;
     210#elif USE(PTHREADS)
     211        typedef pthread_attr_t PlatformRegisters;
     212#else
     213#error Need a thread register struct for this platform
     214#endif
     215       
     216        PlatformRegisters regs;
     217    };
     218   
     219    inline bool operator==(const PlatformThread& other) const;
     220    inline bool operator!=(const PlatformThread& other) const { return !(*this == other); }
     221
     222    inline bool suspend();
     223    inline void resume();
     224    size_t getRegisters(Registers&);
     225    void freeRegisters(Registers&);
     226    std::pair<void*, size_t> captureStack(void* stackTop);
     227
    172228    Thread* next;
    173229    PlatformThread platformThread;
     
    200256}
    201257
    202 static inline PlatformThread getCurrentPlatformThread()
    203 {
    204 #if OS(DARWIN)
    205     return pthread_mach_thread_np(pthread_self());
    206 #elif OS(WINDOWS)
    207     return GetCurrentThread();
    208 #elif USE(PTHREADS)
    209     return pthread_self();
    210 #endif
    211 }
    212 
    213 static inline bool equalThread(const PlatformThread& first, const PlatformThread& second)
     258inline bool MachineThreads::Thread::operator==(const PlatformThread& other) const
    214259{
    215260#if OS(DARWIN) || OS(WINDOWS)
    216     return first == second;
    217 #elif USE(PTHREADS)
    218     return !!pthread_equal(first, second);
     261    return platformThread == other;
     262#elif USE(PTHREADS)
     263    return !!pthread_equal(platformThread, other);
    219264#else
    220265#error Need a way to compare threads on this platform
     
    232277
    233278    threadSpecificSet(m_threadSpecific, this);
    234     Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
     279    Thread* thread = Thread::createForCurrentThread();
    235280
    236281    MutexLocker lock(m_registeredThreadsMutex);
     
    259304{
    260305    MutexLocker lock(m_registeredThreadsMutex);
    261     if (equalThread(platformThread, m_registeredThreads->platformThread)) {
    262         Thread* t = m_registeredThreads;
     306    Thread* t = m_registeredThreads;
     307    if (*t == platformThread) {
    263308        m_registeredThreads = m_registeredThreads->next;
    264309        delete t;
    265310    } else {
    266311        Thread* last = m_registeredThreads;
    267         Thread* t;
    268312        for (t = m_registeredThreads->next; t; t = t->next) {
    269             if (equalThread(t->platformThread, platformThread)) {
     313            if (*t == platformThread) {
    270314                last->next = t->next;
    271315                break;
     
    286330}
    287331
    288 static inline bool suspendThread(const PlatformThread& platformThread)
     332inline bool MachineThreads::Thread::suspend()
    289333{
    290334#if OS(DARWIN)
     
    303347}
    304348
    305 static inline void resumeThread(const PlatformThread& platformThread)
     349inline void MachineThreads::Thread::resume()
    306350{
    307351#if OS(DARWIN)
     
    316360}
    317361
    318 typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
    319 
    320 #if OS(DARWIN)
    321 
    322 #if CPU(X86)
    323 typedef i386_thread_state_t PlatformThreadRegisters;
    324 #elif CPU(X86_64)
    325 typedef x86_thread_state64_t PlatformThreadRegisters;
    326 #elif CPU(PPC)
    327 typedef ppc_thread_state_t PlatformThreadRegisters;
    328 #elif CPU(PPC64)
    329 typedef ppc_thread_state64_t PlatformThreadRegisters;
    330 #elif CPU(ARM)
    331 typedef arm_thread_state_t PlatformThreadRegisters;
    332 #elif CPU(ARM64)
    333 typedef arm_thread_state64_t PlatformThreadRegisters;
    334 #else
    335 #error Unknown Architecture
    336 #endif
    337 
    338 #elif OS(WINDOWS)
    339 typedef CONTEXT PlatformThreadRegisters;
    340 #elif USE(PTHREADS)
    341 typedef pthread_attr_t PlatformThreadRegisters;
    342 #else
    343 #error Need a thread register struct for this platform
    344 #endif
    345 
    346 static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
    347 {
    348 #if OS(DARWIN)
    349 
     362size_t MachineThreads::Thread::getRegisters(MachineThreads::Thread::Registers& registers)
     363{
     364    Thread::Registers::PlatformRegisters& regs = registers.regs;
     365#if OS(DARWIN)
    350366#if CPU(X86)
    351367    unsigned user_count = sizeof(regs)/sizeof(int);
     
    376392        CRASH();
    377393    }
    378     return user_count * sizeof(usword_t);
     394    return user_count * sizeof(uintptr_t);
    379395// end OS(DARWIN)
    380396
     
    400416}
    401417
    402 static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
     418inline void* MachineThreads::Thread::Registers::stackPointer() const
    403419{
    404420#if OS(DARWIN)
     
    468484}
    469485
    470 static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
    471 {
     486void MachineThreads::Thread::freeRegisters(MachineThreads::Thread::Registers& registers)
     487{
     488    Thread::Registers::PlatformRegisters& regs = registers.regs;
    472489#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
    473490    pthread_attr_destroy(&regs);
     
    477494}
    478495
    479 static std::pair<void*, size_t> otherThreadStack(void* stackBase, const PlatformThreadRegisters& registers)
     496std::pair<void*, size_t> MachineThreads::Thread::captureStack(void* stackTop)
    480497{
    481498    void* begin = stackBase;
    482499    void* end = reinterpret_cast<void*>(
    483         WTF::roundUpToMultipleOf<sizeof(void*)>(
    484             reinterpret_cast<uintptr_t>(
    485                 otherThreadStackPointer(registers))));
     500        WTF::roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(stackTop)));
    486501    if (begin > end)
    487502        std::swap(begin, end);
     
    514529void MachineThreads::tryCopyOtherThreadStack(Thread* thread, void* buffer, size_t capacity, size_t* size)
    515530{
    516     PlatformThreadRegisters registers;
    517     size_t registersSize = getPlatformThreadRegisters(thread->platformThread, registers);
    518     std::pair<void*, size_t> stack = otherThreadStack(thread->stackBase, registers);
     531    Thread::Registers registers;
     532    size_t registersSize = thread->getRegisters(registers);
     533    std::pair<void*, size_t> stack = thread->captureStack(registers.stackPointer());
    519534
    520535    bool canCopy = *size + registersSize + stack.second <= capacity;
     
    528543    *size += stack.second;
    529544
    530     freePlatformThreadRegisters(registers);
     545    thread->freeRegisters(registers);
    531546}
    532547
     
    542557    Thread* previousThread = nullptr;
    543558    for (Thread* thread = m_registeredThreads; thread; index++) {
    544         if (!equalThread(thread->platformThread, currentPlatformThread)) {
    545             bool success = suspendThread(thread->platformThread);
     559        if (*thread != currentPlatformThread) {
     560            bool success = thread->suspend();
    546561#if OS(DARWIN)
    547562            if (!success) {
     
    586601
    587602    for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
    588         if (!equalThread(thread->platformThread, currentPlatformThread))
     603        if (*thread != currentPlatformThread)
    589604            tryCopyOtherThreadStack(thread, buffer, capacity, size);
    590605    }
    591606
    592607    for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
    593         if (!equalThread(thread->platformThread, currentPlatformThread))
    594             resumeThread(thread->platformThread);
     608        if (*thread != currentPlatformThread)
     609            thread->resume();
    595610    }
    596611
Note: See TracChangeset for help on using the changeset viewer.