Changeset 195891 in webkit


Ignore:
Timestamp:
Jan 30, 2016 4:53:59 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

Enable SamplingProfiler on POSIX environment
https://bugs.webkit.org/show_bug.cgi?id=153584

Reviewed by Michael Saboff.

.:

Add features.h header check. It will define GLIBC.

  • Source/cmake/OptionsCommon.cmake:

Source/JavaScriptCore:

In this patch, we implement suspend and resume mechanizm for POSIX threads.
And with GLIBC, we can retrieve registers from it.

We take the following strategy.

Suspend side.

  1. install sigaction to the threads.
  2. in the profiler (suspend / resume callers), emit signal with pthread_kill and wait with POSIX semaphore.
  3. in the signal handler, up the POSIX semaphore. Use sem_post because it is the async-signal-safe function in POSIX.
  4. in the signal handler, perform sigsuspend to stop the thread until being resumed.
  5. in the profiler, we can be waken up from the semaphore because (3) ups.

Resume side.

  1. in the profiler, emit signal and wait on the semaphore.
  2. in the signal handler, it is waken up from the sigsuspend.
  3. in the signal handler, up the semaphore.
  4. in the profiler, the profiler is waken up from the semaphore. It is ensured that the given thread is resumed by the signal.
  • heap/MachineStackMarker.cpp:

(pthreadSignalHandlerSuspendResume):
(JSC::MachineThreads::Thread::Thread):
(JSC::MachineThreads::Thread::~Thread):
(JSC::MachineThreads::Thread::suspend):
(JSC::MachineThreads::Thread::resume):
(JSC::MachineThreads::Thread::getRegisters):
(JSC::MachineThreads::Thread::Registers::stackPointer):
(JSC::MachineThreads::Thread::Registers::framePointer):
(JSC::MachineThreads::Thread::Registers::instructionPointer):
(JSC::MachineThreads::Thread::Registers::llintPC):
(JSC::MachineThreads::Thread::freeRegisters):

  • heap/MachineStackMarker.h:
  • runtime/SamplingProfiler.cpp:

(JSC::reportStats):

  • tests/stress/call-varargs-from-inlined-code-with-odd-number-of-arguments.js:
  • tests/stress/call-varargs-from-inlined-code.js:
  • tests/stress/v8-earley-boyer-strict.js:

Source/WTF:

Use GLIBC since mcontext_t layout depends on it.

  • wtf/Platform.h:

Tools:

  • Scripts/run-jsc-stress-tests:
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r195675 r195891  
     12016-01-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Enable SamplingProfiler on POSIX environment
     4        https://bugs.webkit.org/show_bug.cgi?id=153584
     5
     6        Reviewed by Michael Saboff.
     7
     8        Add features.h header check. It will define __GLIBC__.
     9
     10        * Source/cmake/OptionsCommon.cmake:
     11
    1122016-01-27  Alexey Proskuryakov  <ap@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r195882 r195891  
     12016-01-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Enable SamplingProfiler on POSIX environment
     4        https://bugs.webkit.org/show_bug.cgi?id=153584
     5
     6        Reviewed by Michael Saboff.
     7
     8        In this patch, we implement suspend and resume mechanizm for POSIX threads.
     9        And with GLIBC, we can retrieve registers from it.
     10
     11        We take the following strategy.
     12
     13        Suspend side.
     14        1. install sigaction to the threads.
     15        2. in the profiler (suspend / resume callers), emit signal with pthread_kill and wait with POSIX semaphore.
     16        3. in the signal handler, up the POSIX semaphore. Use sem_post because it is the async-signal-safe function in POSIX.
     17        4. in the signal handler, perform sigsuspend to stop the thread until being resumed.
     18        5. in the profiler, we can be waken up from the semaphore because (3) ups.
     19
     20        Resume side.
     21        1. in the profiler, emit signal and wait on the semaphore.
     22        2. in the signal handler, it is waken up from the sigsuspend.
     23        3. in the signal handler, up the semaphore.
     24        4. in the profiler, the profiler is waken up from the semaphore. It is ensured that the given thread is resumed by the signal.
     25
     26        * heap/MachineStackMarker.cpp:
     27        (pthreadSignalHandlerSuspendResume):
     28        (JSC::MachineThreads::Thread::Thread):
     29        (JSC::MachineThreads::Thread::~Thread):
     30        (JSC::MachineThreads::Thread::suspend):
     31        (JSC::MachineThreads::Thread::resume):
     32        (JSC::MachineThreads::Thread::getRegisters):
     33        (JSC::MachineThreads::Thread::Registers::stackPointer):
     34        (JSC::MachineThreads::Thread::Registers::framePointer):
     35        (JSC::MachineThreads::Thread::Registers::instructionPointer):
     36        (JSC::MachineThreads::Thread::Registers::llintPC):
     37        (JSC::MachineThreads::Thread::freeRegisters):
     38        * heap/MachineStackMarker.h:
     39        * runtime/SamplingProfiler.cpp:
     40        (JSC::reportStats):
     41        * tests/stress/call-varargs-from-inlined-code-with-odd-number-of-arguments.js:
     42        * tests/stress/call-varargs-from-inlined-code.js:
     43        * tests/stress/v8-earley-boyer-strict.js:
     44
    1452016-01-29  Filip Pizlo  <fpizlo@apple.com>
    246
  • trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp

    r195865 r195891  
    6666#include <signal.h>
    6767
     68// We use SIGUSR2 to suspend and resume machine threads in JavaScriptCore.
    6869static const int SigThreadSuspendResume = SIGUSR2;
    69 
    70 #if defined(SA_RESTART)
    71 static void pthreadSignalHandlerSuspendResume(int)
    72 {
    73     sigset_t signalSet;
    74     sigemptyset(&signalSet);
    75     sigaddset(&signalSet, SigThreadSuspendResume);
    76     sigsuspend(&signalSet);
    77 }
    78 #endif // defined(SA_RESTART)
     70static StaticLock globalSignalLock;
     71thread_local static std::atomic<JSC::MachineThreads::Thread*> threadLocalCurrentThread;
     72
     73static void pthreadSignalHandlerSuspendResume(int, siginfo_t*, void* ucontext)
     74{
     75    // Touching thread local atomic types from signal handlers is allowed.
     76    JSC::MachineThreads::Thread* thread = threadLocalCurrentThread.load();
     77
     78    if (thread->suspended.load(std::memory_order_acquire)) {
     79        // This is signal handler invocation that is intended to be used to resume sigsuspend.
     80        // So this handler invocation itself should not process.
     81        //
     82        // When signal comes, first, the system calls signal handler. And later, sigsuspend will be resumed. Signal handler invocation always precedes.
     83        // So, the problem never happens that suspended.store(true, ...) will be executed before the handler is called.
     84        // http://pubs.opengroup.org/onlinepubs/009695399/functions/sigsuspend.html
     85        return;
     86    }
     87
     88    struct ucontext* userContext = static_cast<struct ucontext*>(ucontext);
     89    thread->suspendedMachineContext = userContext->uc_mcontext;
     90
     91    // Allow suspend caller to see that this thread is suspended.
     92    // sem_post is async-signal-safe function. It means that we can call this from a signal handler.
     93    // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
     94    //
     95    // And sem_post emits memory barrier that ensures that suspendedMachineContext is correctly saved.
     96    // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11
     97    sem_post(&thread->semaphoreForSuspendResume);
     98
     99    // Reaching here, SigThreadSuspendResume is blocked in this handler (this is configured by sigaction's sa_mask).
     100    // So before calling sigsuspend, SigThreadSuspendResume to this thread is deferred. This ensures that the handler is not executed recursively.
     101    sigset_t blockedSignalSet;
     102    sigfillset(&blockedSignalSet);
     103    sigdelset(&blockedSignalSet, SigThreadSuspendResume);
     104    sigsuspend(&blockedSignalSet);
     105
     106    // Allow resume caller to see that this thread is resumed.
     107    sem_post(&thread->semaphoreForSuspendResume);
     108}
    79109#endif // USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
    80110
     
    300330    , stackEnd(end)
    301331{
    302 #if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN) && defined(SA_RESTART)
    303     // if we have SA_RESTART, enable SIGUSR2 debugging mechanism
    304     struct sigaction action;
    305     action.sa_handler = pthreadSignalHandlerSuspendResume;
    306     sigemptyset(&action.sa_mask);
    307     action.sa_flags = SA_RESTART;
    308     sigaction(SigThreadSuspendResume, &action, 0);
    309 
    310     sigset_t mask;
    311     sigemptyset(&mask);
    312     sigaddset(&mask, SigThreadSuspendResume);
    313     pthread_sigmask(SIG_UNBLOCK, &mask, 0);
    314 #elif OS(WINDOWS)
     332#if OS(WINDOWS)
    315333    ASSERT(platformThread == GetCurrentThreadId());
    316334    bool isSuccessful =
     
    318336            &platformThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
    319337    RELEASE_ASSERT(isSuccessful);
     338#elif USE(PTHREADS) && !OS(DARWIN)
     339    threadLocalCurrentThread.store(this);
     340
     341    // Signal handlers are process global configuration.
     342    static std::once_flag initializeSignalHandler;
     343    std::call_once(initializeSignalHandler, [] {
     344        // Intentionally block SigThreadSuspendResume in the handler.
     345        // SigThreadSuspendResume will be allowed in the handler by sigsuspend.
     346        struct sigaction action;
     347        sigemptyset(&action.sa_mask);
     348        sigaddset(&action.sa_mask, SigThreadSuspendResume);
     349
     350        action.sa_sigaction = pthreadSignalHandlerSuspendResume;
     351        action.sa_flags = SA_RESTART | SA_SIGINFO;
     352        sigaction(SigThreadSuspendResume, &action, 0);
     353    });
     354
     355    sigset_t mask;
     356    sigemptyset(&mask);
     357    sigaddset(&mask, SigThreadSuspendResume);
     358    pthread_sigmask(SIG_UNBLOCK, &mask, 0);
     359
     360    sem_init(&semaphoreForSuspendResume, /* Only available in this process. */ 0, /* Initial value for the semaphore. */ 0);
    320361#endif
    321362}
     
    325366#if OS(WINDOWS)
    326367    CloseHandle(platformThreadHandle);
     368#elif USE(PTHREADS) && !OS(DARWIN)
     369    sem_destroy(&semaphoreForSuspendResume);
    327370#endif
    328371}
     
    338381    return threadIsSuspended;
    339382#elif USE(PTHREADS)
    340     pthread_kill(platformThread, SigThreadSuspendResume);
     383    ASSERT_WITH_MESSAGE(getCurrentPlatformThread() != platformThread, "Currently we don't support suspend the current thread itself.");
     384    {
     385        // During suspend, suspend or resume should not be executed from the other threads.
     386        // We use global lock instead of per thread lock.
     387        // Consider the following case, there are threads A and B.
     388        // And A attempt to suspend B and B attempt to suspend A.
     389        // A and B send signals. And later, signals are delivered to A and B.
     390        // In that case, both will be suspended.
     391        LockHolder lock(globalSignalLock);
     392        if (!suspendCount) {
     393            // Ideally, we would like to use pthread_sigqueue. It allows us to pass the argument to the signal handler.
     394            // But it can be used in a few platforms, like Linux.
     395            // Instead, we use Thread* stored in the thread local storage to pass it to the signal handler.
     396            if (pthread_kill(platformThread, SigThreadSuspendResume) == ESRCH)
     397                return false;
     398            sem_wait(&semaphoreForSuspendResume);
     399            // Release barrier ensures that this operation is always executed after all the above processing is done.
     400            suspended.store(true, std::memory_order_release);
     401        }
     402        ++suspendCount;
     403    }
    341404    return true;
    342405#else
     
    352415    ResumeThread(platformThreadHandle);
    353416#elif USE(PTHREADS)
    354     pthread_kill(platformThread, SigThreadSuspendResume);
     417    {
     418        // During resume, suspend or resume should not be executed from the other threads.
     419        LockHolder lock(globalSignalLock);
     420        if (suspendCount == 1) {
     421            // When allowing SigThreadSuspendResume interrupt in the signal handler by sigsuspend and SigThreadSuspendResume is actually issued,
     422            // the signal handler itself will be called once again.
     423            // There are several ways to distinguish the handler invocation for suspend and resume.
     424            // 1. Use different signal numbers. And check the signal number in the handler.
     425            // 2. Use some arguments to distinguish suspend and resume in the handler. If pthread_sigqueue can be used, we can take this.
     426            // 3. Use thread local storage with atomic variables in the signal handler.
     427            // In this implementaiton, we take (3). suspended flag is used to distinguish it.
     428            if (pthread_kill(platformThread, SigThreadSuspendResume) == ESRCH)
     429                return;
     430            sem_wait(&semaphoreForSuspendResume);
     431            // Release barrier ensures that this operation is always executed after all the above processing is done.
     432            suspended.store(false, std::memory_order_release);
     433        }
     434        --suspendCount;
     435    }
    355436#else
    356437#error Need a way to resume threads on this platform
     
    398479    return sizeof(CONTEXT);
    399480#elif USE(PTHREADS)
    400     pthread_attr_init(&regs);
     481    pthread_attr_init(&regs.attribute);
    401482#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
    402483#if !OS(OPENBSD)
    403484    // e.g. on FreeBSD 5.4, neundorf@kde.org
    404     pthread_attr_get_np(platformThread, &regs);
     485    pthread_attr_get_np(platformThread, &regs.attribute);
    405486#endif
    406487#else
    407488    // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
    408     pthread_getattr_np(platformThread, &regs);
    409 #endif
     489    pthread_getattr_np(platformThread, &regs.attribute);
     490#endif
     491    regs.machineContext = suspendedMachineContext;
    410492    return 0;
    411493#else
     
    464546
    465547#elif USE(PTHREADS)
     548
     549#if defined(__GLIBC__) && ENABLE(JIT)
     550
     551#if CPU(X86)
     552    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_ESP]);
     553#elif CPU(X86_64)
     554    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_RSP]);
     555#elif CPU(ARM)
     556    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.arm_sp);
     557#elif CPU(ARM64)
     558    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.sp);
     559#elif CPU(MIPS)
     560    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[29]);
     561#else
     562#error Unknown Architecture
     563#endif
     564
     565#else
    466566    void* stackBase = 0;
    467567    size_t stackSize = 0;
     
    472572    stackSize = ss.ss_size;
    473573#else
    474     int rc = pthread_attr_getstack(&regs, &stackBase, &stackSize);
     574    int rc = pthread_attr_getstack(&regs.attribute, &stackBase, &stackSize);
    475575#endif
    476576    (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
    477577    ASSERT(stackBase);
    478578    return static_cast<char*>(stackBase) + stackSize;
     579#endif
     580
    479581#else
    480582#error Need a way to get the stack pointer for another thread on this platform
     
    528630#endif
    529631
     632#elif defined(__GLIBC__)
     633
     634// The following sequence depends on glibc's sys/ucontext.h.
     635#if CPU(X86)
     636    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_EBP]);
     637#elif CPU(X86_64)
     638    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_RBP]);
     639#elif CPU(ARM)
     640    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.arm_fp);
     641#elif CPU(ARM64)
     642    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.regs[29]);
     643#elif CPU(MIPS)
     644    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[30]);
     645#else
     646#error Unknown Architecture
     647#endif
     648
    530649#else
    531650#error Need a way to get the frame pointer for another thread on this platform
     
    573692#elif CPU(X86_64)
    574693    return reinterpret_cast<void*>((uintptr_t) regs.Rip);
     694#else
     695#error Unknown Architecture
     696#endif
     697
     698#elif defined(__GLIBC__)
     699
     700// The following sequence depends on glibc's sys/ucontext.h.
     701#if CPU(X86)
     702    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_EIP]);
     703#elif CPU(X86_64)
     704    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_RIP]);
     705#elif CPU(ARM)
     706    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.arm_pc);
     707#elif CPU(ARM64)
     708    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.pc);
     709#elif CPU(MIPS)
     710    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.pc);
    575711#else
    576712#error Unknown Architecture
     
    635771#endif
    636772
     773#elif defined(__GLIBC__)
     774
     775// The following sequence depends on glibc's sys/ucontext.h.
     776#if CPU(X86)
     777    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_ESI]);
     778#elif CPU(X86_64)
     779    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[REG_R8]);
     780#elif CPU(ARM)
     781    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.arm_r8);
     782#elif CPU(ARM64)
     783    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.regs[4]);
     784#elif CPU(MIPS)
     785    return reinterpret_cast<void*>((uintptr_t) regs.machineContext.gregs[12]);
     786#else
     787#error Unknown Architecture
     788#endif
     789
    637790#else
    638791#error Need a way to get the LLIntPC for another thread on this platform
     
    645798    Thread::Registers::PlatformRegisters& regs = registers.regs;
    646799#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
    647     pthread_attr_destroy(&regs);
     800    pthread_attr_destroy(&regs.attribute);
    648801#else
    649802    UNUSED_PARAM(regs);
  • trunk/Source/JavaScriptCore/heap/MachineStackMarker.h

    r195865 r195891  
    3030#if OS(DARWIN)
    3131#include <mach/thread_act.h>
     32#endif
     33
     34#if USE(PTHREADS) && !OS(WINDOWS) && !OS(DARWIN)
     35#include <semaphore.h>
     36#include <signal.h>
    3237#endif
    3338
     
    96101            typedef CONTEXT PlatformRegisters;
    97102#elif USE(PTHREADS)
    98             typedef pthread_attr_t PlatformRegisters;
     103            struct PlatformRegisters {
     104                pthread_attr_t attribute;
     105                mcontext_t machineContext;
     106            };
    99107#else
    100108#error Need a thread register struct for this platform
     
    119127#if OS(WINDOWS)
    120128        HANDLE platformThreadHandle;
     129#elif USE(PTHREADS) && !OS(DARWIN)
     130        sem_t semaphoreForSuspendResume;
     131        mcontext_t suspendedMachineContext;
     132        int suspendCount { 0 };
     133        std::atomic<bool> suspended { false };
    121134#endif
    122135    };
  • trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp

    r195865 r195891  
    6767        if (!sReportStatsOnlyWhenTheyreAboveThreshold || (sNumFailedWalks / sNumTotalWalks > sWalkErrorPercentage)) {
    6868            dataLogF("Num total walks: %llu. Failed walks percent: %lf\n",
    69                 static_cast<uint64_t>(sNumTotalWalks), sNumFailedWalks / sNumTotalWalks);
     69                static_cast<unsigned long long>(sNumTotalWalks), sNumFailedWalks / sNumTotalWalks);
    7070        }
    7171    }
  • trunk/Source/JavaScriptCore/tests/stress/call-varargs-from-inlined-code-with-odd-number-of-arguments.js

    r166142 r195891  
     1// [DFG] call-varargs-from-inlined-code-with-odd-number-of-arguments.js fails in POSIX environment if SamplingProfiler is enabled
     2// https://bugs.webkit.org/show_bug.cgi?id=153704
     3//@ if $hostOS == "linux" then defaultNoSamplingProfilerRun else defaultRun end
     4
    15function foo(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) {
    26    return a * 2 + b * 3 + c * 5 + d * 7 + e * 11 + f * 13 + g * 17 + h * 19 + i * 23 + j * 29 + k * 31 + l * 37 + m * 41 + n * 43 + o * 47 + p * 53 + q * 59 + r * 61 + s * 67 + t * 71 + u * 73 + v * 79 + w * 83 + x * 89 + y * 97;
  • trunk/Source/JavaScriptCore/tests/stress/call-varargs-from-inlined-code.js

    r166142 r195891  
     1// [DFG] call-varargs-from-inlined-code-with-odd-number-of-arguments.js fails in POSIX environment if SamplingProfiler is enabled
     2// https://bugs.webkit.org/show_bug.cgi?id=153704
     3//@ if $hostOS == "linux" then defaultNoSamplingProfilerRun else defaultRun end
     4
    15function foo(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) {
    26    return a * 2 + b * 3 + c * 5 + d * 7 + e * 11 + f * 13 + g * 17 + h * 19 + i * 23 + j * 29 + k * 31 + l * 37 + m * 41 + n * 43 + o * 47 + p * 53 + q * 59 + r * 61 + s * 67 + t * 71 + u * 73 + v * 79 + w * 83 + x * 89 + y * 97 + z * 101;
  • trunk/Source/JavaScriptCore/tests/stress/v8-earley-boyer-strict.js

    r189335 r195891  
     1// [DFG] call-varargs-from-inlined-code-with-odd-number-of-arguments.js fails in POSIX environment if SamplingProfiler is enabled
     2// https://bugs.webkit.org/show_bug.cgi?id=153704
     3//@ if $hostOS == "linux" then defaultNoSamplingProfilerRun else defaultRun end
    14// This file is automatically generated by scheme2js, except for the
    25// benchmark harness code at the beginning and end of the file.
  • trunk/Source/WTF/ChangeLog

    r195743 r195891  
     12016-01-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Enable SamplingProfiler on POSIX environment
     4        https://bugs.webkit.org/show_bug.cgi?id=153584
     5
     6        Reviewed by Michael Saboff.
     7
     8        Use __GLIBC__ since mcontext_t layout depends on it.
     9
     10        * wtf/Platform.h:
     11
    1122016-01-28  Darin Adler  <darin@apple.com>
    213
  • trunk/Source/WTF/wtf/Platform.h

    r195644 r195891  
    427427/* Operating environments */
    428428
     429/* Standard libraries */
     430#if defined(HAVE_FEATURES_H) && HAVE_FEATURES_H
     431/* If the included features.h is glibc's one, __GLIBC__ is defined. */
     432#include <features.h>
     433#endif
     434
    429435/* FIXME: these are all mixes of OS, operating environment and policy choices. */
    430436/* PLATFORM(EFL) */
     
    799805
    800806/* The SamplingProfiler is the probabilistic and low-overhead profiler used by
    801  * JSC to measure where time is spent inside a JavaScript program. */
    802 #if (OS(DARWIN) || OS(WINDOWS)) && ENABLE(JIT)
     807 * JSC to measure where time is spent inside a JavaScript program.
     808 * In configurations other than Windows and Darwin, because layout of mcontext_t depends on standard libraries (like glibc),
     809 * sampling profiler is enabled if WebKit uses pthreads and glibc. */
     810#if (OS(DARWIN) || OS(WINDOWS) || (USE(PTHREADS) && defined(__GLIBC__))) && ENABLE(JIT)
    803811#define ENABLE_SAMPLING_PROFILER 1
    804812#else
  • trunk/Source/cmake/OptionsCommon.cmake

    r191936 r195891  
    148148    set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)
    149149endif ()
     150
     151# Check whether features.h header exists.
     152# Including glibc's one defines __GLIBC__, that is used in Platform.h
     153include(CheckIncludeFiles)
     154check_include_files(features.h HAVE_FEATURES_H)
     155SET_AND_EXPOSE_TO_BUILD(HAVE_FEATURES_H ${HAVE_FEATURES_H})
  • trunk/Tools/ChangeLog

    r195843 r195891  
     12016-01-30  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Enable SamplingProfiler on POSIX environment
     4        https://bugs.webkit.org/show_bug.cgi?id=153584
     5
     6        Reviewed by Michael Saboff.
     7
     8        * Scripts/run-jsc-stress-tests:
     9
    1102016-01-29  Nikos Andronikos  <nikos.andronikos-webkit@cisra.canon.com.au>
    211
  • trunk/Tools/Scripts/run-jsc-stress-tests

    r194899 r195891  
    905905end
    906906
     907def defaultNoSamplingProfilerRun
     908    runDefault
     909    runAlwaysTriggerCopyPhase
     910    if $jitTests
     911        runNoLLInt
     912        runNoCJITValidatePhases
     913        runDFGEager
     914        runDFGEagerNoCJITValidate
     915        runDefaultFTL
     916        runFTLNoCJITNoPutStackValidate
     917        runFTLNoCJITNoInlineValidate
     918        runFTLEager
     919        runFTLEagerNoCJITValidate
     920        runFTLNoCJITSmallPool
     921        runDFGMaximalFlushPhase
     922    end
     923end
     924
    907925def runProfiler
    908926    if $remote or ($architecture !~ /x86/i and $hostOS == "darwin") or ($hostOS == "windows")
Note: See TracChangeset for help on using the changeset viewer.