WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
171262
[JSC] Handle PhantomSpread in LoadVarargs as the same to the others
https://bugs.webkit.org/show_bug.cgi?id=171262
Summary
[JSC] Handle PhantomSpread in LoadVarargs as the same to the others
Yusuke Suzuki
Reported
2017-04-25 00:22:10 PDT
[JSC] Handle PhantomSpread in LoadVarargs as the same to the others
Attachments
Patch
(11.96 KB, patch)
2017-04-25 00:23 PDT
,
Yusuke Suzuki
saam
: review+
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Yusuke Suzuki
Comment 1
2017-04-25 00:23:25 PDT
Created
attachment 308074
[details]
Patch
Yusuke Suzuki
Comment 2
2017-04-25 05:49:43 PDT
Comment on
attachment 308074
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=308074&action=review
> Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp:880 > InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame;
This is buggy part of this patch. But we cannot test it since the following code, function a(...args) { return b(args); } function b(args) { return c(...args); } function c(a0, a1, a2, a3, a4) { return a2; } a(0, 1, 2, 3, 4, 5); will emit PutStack for args, and make it usual Spread & CreateRest instead of PhantomSpread. Thus, we cannot observe this bug fixed in this patch.
Saam Barati
Comment 3
2017-04-25 14:29:43 PDT
Comment on
attachment 308074
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=308074&action=review
>> Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp:880 >> InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame; > > This is buggy part of this patch. But we cannot test it since the following code, > > function a(...args) > { > return b(args); > } > > function b(args) > { > return c(...args); > } > > function c(a0, a1, a2, a3, a4) > { > return a2; > } > > a(0, 1, 2, 3, 4, 5); > > will emit PutStack for args, and make it usual Spread & CreateRest instead of PhantomSpread. > Thus, we cannot observe this bug fixed in this patch.
I'm confused. There exists no test for this? How is that possible?
Yusuke Suzuki
Comment 4
2017-04-26 07:15:04 PDT
Comment on
attachment 308074
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=308074&action=review
>>> Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp:880 >>> InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame; >> >> This is buggy part of this patch. But we cannot test it since the following code, >> >> function a(...args) >> { >> return b(args); >> } >> >> function b(args) >> { >> return c(...args); >> } >> >> function c(a0, a1, a2, a3, a4) >> { >> return a2; >> } >> >> a(0, 1, 2, 3, 4, 5); >> >> will emit PutStack for args, and make it usual Spread & CreateRest instead of PhantomSpread. >> Thus, we cannot observe this bug fixed in this patch. > > I'm confused. There exists no test for this? How is that possible?
The problem is that `spread->child1()->origin.semantic.inlineCallFrame` could be different from `spread->origin.semantic.inlineCallFrame`. If it happens with LoadVarargs, the observable bug occurs. However, currently, this case does not occur. This is just because PutStack always escapes the spread in this case. So it is not testable. But it's not logically correct and it breaks things if this phase is merged into Object Allocation Sinking.
Saam Barati
Comment 5
2017-04-26 12:52:05 PDT
Oh I see, this is because we run putStackSinkingPhase after arguments elimination :(
Saam Barati
Comment 6
2017-04-26 12:54:29 PDT
(In reply to Saam Barati from
comment #5
)
> Oh I see, this is because we run putStackSinkingPhase after arguments > elimination :(
I wonder if we should run putStackSinkingPhase first, then run argumentsElimination, and then run putStackSinkingPhase again but only if argumentsElimination did anything. We should obviously be able to transform your example program to not allocate Createrest/Spread. Fil, Yusuke, any thoughts on this proposal?
Saam Barati
Comment 7
2017-04-26 12:57:45 PDT
Comment on
attachment 308074
[details]
Patch r=me. I agree with this change even if we have the PutStack issue.
Saam Barati
Comment 8
2017-04-26 13:00:07 PDT
I applied your change locally, along with this change to Plan: ``` if (Options::usePutStackSinking()) RUN_PHASE(performPutStackSinking); changed = false; RUN_PHASE(performArgumentsElimination); if (changed && Options::usePutStackSinking()) RUN_PHASE(performPutStackSinking); ``` And ran this program: ``` "use strict"; function assert(b) { if (!b) throw new Error("Bad"); } function foo(...args) { return bar(args); } noInline(foo); function bar(args) { return baz(...args); } function baz(a, b) { return a + b; } for (let i = 0; i < 10000; ++i) { assert(foo(i, i+1) === (i + (i + 1))); } ``` And your patch fixes the crash.
Filip Pizlo
Comment 9
2017-04-26 13:33:31 PDT
(In reply to Saam Barati from
comment #6
)
> (In reply to Saam Barati from
comment #5
) > > Oh I see, this is because we run putStackSinkingPhase after arguments > > elimination :( > > I wonder if we should run putStackSinkingPhase first, then run > argumentsElimination, and then run putStackSinkingPhase again but only if > argumentsElimination did anything. > > We should obviously be able to transform your example program to not > allocate Createrest/Spread. > > Fil, Yusuke, any thoughts on this proposal?
I think that we need to combine the PutStack, ArgumentsElimination, and ObjectAllocationSinking phases should in the long term be combined into one phase, that assumes that nothing escapes as its initial bottom result and then builds up from there. Otherwise trying to fixpoint these phases means we start at top and incremnetally optimize.
Yusuke Suzuki
Comment 10
2017-04-27 01:55:24 PDT
(In reply to Filip Pizlo from
comment #9
)
> (In reply to Saam Barati from
comment #6
) > > (In reply to Saam Barati from
comment #5
) > > > Oh I see, this is because we run putStackSinkingPhase after arguments > > > elimination :( > > > > I wonder if we should run putStackSinkingPhase first, then run > > argumentsElimination, and then run putStackSinkingPhase again but only if > > argumentsElimination did anything. > > > > We should obviously be able to transform your example program to not > > allocate Createrest/Spread. > > > > Fil, Yusuke, any thoughts on this proposal? > > I think that we need to combine the PutStack, ArgumentsElimination, and > ObjectAllocationSinking phases should in the long term be combined into one > phase, that assumes that nothing escapes as its initial bottom result and > then builds up from there. > > Otherwise trying to fixpoint these phases means we start at top and > incremnetally optimize.
Agreed.
Yusuke Suzuki
Comment 11
2017-04-27 01:57:00 PDT
(In reply to Saam Barati from
comment #8
)
> I applied your change locally, along with this change to Plan: > > ``` > if (Options::usePutStackSinking()) > RUN_PHASE(performPutStackSinking); > changed = false; > RUN_PHASE(performArgumentsElimination); > if (changed && Options::usePutStackSinking()) > RUN_PHASE(performPutStackSinking); > ``` > > And ran this program: > ``` > "use strict"; > > function assert(b) { > if (!b) > throw new Error("Bad"); > } > > function foo(...args) { > return bar(args); > } > noInline(foo); > > function bar(args) { > return baz(...args); > } > > function baz(a, b) { > return a + b; > } > > for (let i = 0; i < 10000; ++i) { > assert(foo(i, i+1) === (i + (i + 1))); > } > ``` > > And your patch fixes the crash.
Yeah. I've added the above code to the test too to ensure this works if PutStack sinking phase is merged.
Yusuke Suzuki
Comment 12
2017-04-27 01:59:19 PDT
Committed
r215860
: <
http://trac.webkit.org/changeset/215860
>
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