WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
153584
Enable SamplingProfiler on POSIX environment
https://bugs.webkit.org/show_bug.cgi?id=153584
Summary
Enable SamplingProfiler on POSIX environment
Yusuke Suzuki
Reported
2016-01-27 22:47:58 PST
Discussed with Saam, and my rough design is as follows. = Suspend 1. in the JS thread, install sigaction to the JS execution thread (This should be done in the constructor of the MachineThread) 2. in the profiler, 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 the UNIX environment[1]. 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. [1]:
http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
NOTE: Be careful to sigaction timing. Should not emit pthread_kill for the thread that does not install signal handlers yet. (But in the current case, it should not be possible). = Resume 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.
Attachments
Patch
(18.34 KB, patch)
2016-01-28 08:29 PST
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Patch
(18.83 KB, patch)
2016-01-28 10:21 PST
,
Yusuke Suzuki
msaboff
: review+
Details
Formatted Diff
Diff
Patch
(5.11 KB, patch)
2016-01-30 03:45 PST
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Yusuke Suzuki
Comment 1
2016-01-28 08:29:53 PST
Created
attachment 270116
[details]
Patch
Yusuke Suzuki
Comment 2
2016-01-28 08:53:39 PST
Comment on
attachment 270116
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=270116&action=review
some notes. I'll fix some build failures.
> Source/JavaScriptCore/heap/MachineStackMarker.cpp:-67 > -#if defined(SA_RESTART)
I think this ifdef is not used anymore. Because Thread::suspend / resume always emits signals. But signal handler is only installed when SA_RESTART is defined. So in the environment that there is no SA_RESTART, the process will be terminated.
> Source/WTF/wtf/Platform.h:433 > +#endif
Oops, I'll fix this part.
Yusuke Suzuki
Comment 3
2016-01-28 09:10:37 PST
Comment on
attachment 270116
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=270116&action=review
> Source/JavaScriptCore/heap/MachineStackMarker.h:132 > + int suspendCount;
Oops, I'll set { 0 }.
Yusuke Suzuki
Comment 4
2016-01-28 09:40:48 PST
Comment on
attachment 270116
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=270116&action=review
> Source/JavaScriptCore/heap/MachineStackMarker.cpp:377 > + LockHolder lock(suspendLock);
I'll change this lock to the static global lock. Consider the following case, there are threads A and B. And A attempt to suspend B and B attempt to suspend A. In that case, if A and B can emit pthread_kill, both will be suspended.
Yusuke Suzuki
Comment 5
2016-01-28 10:21:20 PST
Created
attachment 270125
[details]
Patch
Yusuke Suzuki
Comment 6
2016-01-28 11:02:52 PST
Comment on
attachment 270125
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=270125&action=review
Add notes.
> Source/JavaScriptCore/heap/MachineStackMarker.cpp:74 > +
And we should note that, when signal comes, first, system calls signal handler. And later, sigsuspend will be resumed. Signal handler invocation always precedes.
http://pubs.opengroup.org/onlinepubs/009695399/functions/sigsuspend.html
"If the action is to execute a signal-catching function, then sigsuspend() shall return after the signal-catching function returns, with the signal mask restored to the set that existed prior to the sigsuspend() call." So, the probelm never happens that suspended.store(true, ...) will be executed before the handler is called. Later, I'll insert this note here.
Yusuke Suzuki
Comment 7
2016-01-28 11:08:11 PST
Comment on
attachment 270125
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=270125&action=review
> Source/JavaScriptCore/heap/MachineStackMarker.cpp:384 > + LockHolder lock(globalSignalLock);
One approach to avoid global lock is that, 1. each thread has a lock. 2. when suspending / resuming, we acquire (1) the suspended thread's lock and (2) the current thread's lock at the same time. (using std::lock lock(A, B) can avoid dead lock :)) But I think the global lock is enough in the meantime.
Michael Saboff
Comment 8
2016-01-28 11:12:03 PST
Comment on
attachment 270125
[details]
Patch r=me It would be good if you could also implement MachineThreads::Thread::Registers::stackPointer() the same way.
Yusuke Suzuki
Comment 9
2016-01-28 21:32:18 PST
(In reply to
comment #8
)
> Comment on
attachment 270125
[details]
> Patch > > r=me
Thank you for your review!
> > It would be good if you could also implement > MachineThreads::Thread::Registers::stackPointer() the same way.
Yeah! It is nice. While instructionPointer() and framePointer() are only used for SamplingProfiler (And only built with ENABLE_SAMPLING_PROFILER), stackPointer() is always used to retrieve stack areas for conservative GC. Currently, only ENABLE_SAMPLING_PROFILER's configuration can retrieve stack pointers. So under non ENABLE_SAMPLING_PROFILER environment, we still need to keep current portable implementation (using pthread). But I think it's not good. Ideally, we would like to support all the supported environment, make ENABLE_SAMPLING_PROFILER always on and drop current portable implementation completely. So, I'll discuss what platform (CPU arch, OS, and standard library (BSD LIBC, GLIBC, Android Bionic etc.)) existing ports (GTK and EFL) support. And at that time, we fill all the platform specific code and implement the above too :)
https://bugs.webkit.org/show_bug.cgi?id=153638
Yusuke Suzuki
Comment 10
2016-01-28 21:33:35 PST
(In reply to
comment #9
)
> > Yeah! It is nice. > > While instructionPointer() and framePointer() are only used for > SamplingProfiler (And only built with ENABLE_SAMPLING_PROFILER), > stackPointer() is always used to retrieve stack areas for conservative GC. > > Currently, only ENABLE_SAMPLING_PROFILER's configuration can retrieve stack > pointers. So under non ENABLE_SAMPLING_PROFILER environment, we still need > to keep current portable implementation (using pthread). But I think it's > not good. > > Ideally, we would like to support all the supported environment, make > ENABLE_SAMPLING_PROFILER always on and drop current portable implementation > completely. > > So, I'll discuss what platform (CPU arch, OS, and standard library (BSD > LIBC, GLIBC, Android Bionic etc.)) existing ports (GTK and EFL) support. > And at that time, we fill all the platform specific code and implement the > above too :) > >
https://bugs.webkit.org/show_bug.cgi?id=153638
Or, maybe, for fallback, keeping pthread portable implementation may be nice...
Yusuke Suzuki
Comment 11
2016-01-29 05:22:15 PST
Hmm, the current implementation almost works fine. But only call-varargs-from-inlined-code-with-odd-number-of-arguments.js with ftl-no-cjit-validate-sampling-profiler mode causes an error. It reports that expected value is different, value becomes NaN. I'm still not sure why it is caused. But after investigating that, 1. It is caused in DFG phase. During DFG, the register becomes unexpected value. 2. I removed all the logic execpt for pthread_kill. signal handler is empty, and suspend and resume just calls pthread_kill and do nothing more. SamplingProfiler just calls suspend() and resume() and do nothing more. Even in that case, still crash occurs.
Saam Barati
Comment 12
2016-01-29 17:12:54 PST
Yusuke, I just landed a patch that adds one more register in
http://trac.webkit.org/changeset/195865
The function is called llintPC(). Can you also add it in your patch? It returns whichever register regT4 is on the particular ISA.
Saam Barati
Comment 13
2016-01-29 17:14:12 PST
(In reply to
comment #11
)
> Hmm, the current implementation almost works fine. > But only call-varargs-from-inlined-code-with-odd-number-of-arguments.js with > ftl-no-cjit-validate-sampling-profiler mode causes an error. It reports that > expected value is different, value becomes NaN. > > I'm still not sure why it is caused. But after investigating that, > > 1. It is caused in DFG phase. During DFG, the register becomes unexpected > value. > 2. I removed all the logic execpt for pthread_kill. signal handler is empty, > and suspend and resume just calls pthread_kill and do nothing more. > SamplingProfiler just calls suspend() and resume() and do nothing more. Even > in that case, still crash occurs.
Is this a recent regression? Does it happen on ToT? Or does this have to do w/ ::stackPointer()?
Yusuke Suzuki
Comment 14
2016-01-30 03:35:35 PST
(In reply to
comment #12
)
> Yusuke, > I just landed a patch that adds one more register in >
http://trac.webkit.org/changeset/195865
> The function is called llintPC(). > Can you also add it in your patch? It returns whichever register regT4 > is on the particular ISA.
Sure!
Yusuke Suzuki
Comment 15
2016-01-30 03:45:27 PST
Created
attachment 270304
[details]
Patch Simple test patch that causes DFG issue
Yusuke Suzuki
Comment 16
2016-01-30 03:52:56 PST
(In reply to
comment #13
)
> Is this a recent regression? Does it happen on ToT? > Or does this have to do w/ ::stackPointer()?
Without stackPointer change. And even if we just call signal and do nothing, the issue occurs. I think, the above patch itself does not have any problems and DFG or elsewhere have some problem... I uploaded some very very simple patch. That just emit signal in ::suspend and do nothing in ::resume. Signal handler does nothing. And SamplingProfiler just calls suspend and resume periodically. Even in the above situation, call-varargs-from-inlined-code-with-odd-number-of-arguments.js sometimes fails. So I think the following situation. 1. Signal handler is set with SA_RESTART. But some system calls does not restart. For example, sleep, usleep are the cases in UNIX. We need to fix this anyway (I'll open the bug for that) 2. So, in some place, sleep is interrupted. 3. As a result, the path that is rarely taken may be taken. For example, if you set some threshold time for invoking DFG, it may not be executed in the usual test cases. But due to interrupted sleep, it may be invoked. 4. And since this path has some issue, it causes the test failure, the result becomes NaN. So I think there are some issues in DFG because when disabling DFG (with env variables), the issue does not occur. So in the meantime, I'll land the patch with stackPointer and LLInt PC change with masking the above test. And I'll open 2 issues. 1. Making non-restarted syscalls signal-safe. (Like sleep) 2. Tracking call-varargs-from-inlined-code-with-odd-number-of-arguments.js issue
Yusuke Suzuki
Comment 17
2016-01-30 04:54:09 PST
Committed
r195891
: <
http://trac.webkit.org/changeset/195891
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug