WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED WONTFIX
65290
DFG speculative JIT does not implement load elimination for GetById
https://bugs.webkit.org/show_bug.cgi?id=65290
Summary
DFG speculative JIT does not implement load elimination for GetById
Filip Pizlo
Reported
2011-07-27 15:15:32 PDT
The DFG JIT has most of the information that it needs for performing load elimination on GetById. Currently it only does load elimination for GetByVal. It should also do it for GetById, and should take care to handle cases where GetById or PutById might cause a side-effect that invalidates the elimination of the load.
Attachments
the patch
(86.98 KB, patch)
2011-07-27 15:23 PDT
,
Filip Pizlo
no flags
Details
Formatted Diff
Diff
the patch (fix style)
(87.01 KB, patch)
2011-07-27 16:34 PDT
,
Filip Pizlo
no flags
Details
Formatted Diff
Diff
the patch (fix windows)
(88.54 KB, patch)
2011-07-27 18:33 PDT
,
Filip Pizlo
no flags
Details
Formatted Diff
Diff
the patch (attempt to fix windows, again)
(88.66 KB, patch)
2011-07-27 22:54 PDT
,
Filip Pizlo
barraclough
: review-
oliver
: commit-queue-
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Filip Pizlo
Comment 1
2011-07-27 15:23:11 PDT
Created
attachment 102194
[details]
the patch I'd let this patch simmer before reviewing it. I'm not expecting it to pass EWS in its current state.
WebKit Review Bot
Comment 2
2011-07-27 15:26:02 PDT
Attachment 102194
[details]
did not pass style-queue: Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/JavaScriptCore/API/JSCallbackObject..." exit_code: 1 Source/JavaScriptCore/dfg/DFGAliasTracker.h:179: Missing spaces around / [whitespace/operators] [3] Source/JavaScriptCore/runtime/JSObject.h:111: The parameter name "value" adds no information, so it should be removed. [readability/parameter_name] [5] Source/JavaScriptCore/runtime/JSObject.h:283: The parameter name "value" adds no information, so it should be removed. [readability/parameter_name] [5] Source/JavaScriptCore/runtime/JSObject.h:382: The parameter name "value" adds no information, so it should be removed. [readability/parameter_name] [5] Source/JavaScriptCore/runtime/JSValue.h:212: Should have only a single space after a punctuation in a comment. [whitespace/comments] [5] Source/JavaScriptCore/dfg/DFGJITCompiler.cpp:453: Should have only a single space after a punctuation in a comment. [whitespace/comments] [5] Source/JavaScriptCore/runtime/Operations.h:29: Alphabetical sorting problem. [build/include_order] [4] Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h:926: The parameter name "recovery" adds no information, so it should be removed. [readability/parameter_name] [5] Total errors found: 8 in 25 files If any of these errors are false positives, please file a bug against check-webkit-style.
Filip Pizlo
Comment 3
2011-07-27 16:34:05 PDT
Created
attachment 102201
[details]
the patch (fix style) This fixes style. I've also rerun tests on the Mac. I will mark as ? when the other bots are happy.
Filip Pizlo
Comment 4
2011-07-27 18:33:13 PDT
Created
attachment 102215
[details]
the patch (fix windows) More fixes in this patch, but I'm still suspecting bot fails.
Filip Pizlo
Comment 5
2011-07-27 22:54:01 PDT
Created
attachment 102228
[details]
the patch (attempt to fix windows, again)
Gavin Barraclough
Comment 6
2011-07-29 16:09:31 PDT
Comment on
attachment 102228
[details]
the patch (attempt to fix windows, again) View in context:
https://bugs.webkit.org/attachment.cgi?id=102228&action=review
I think we need to blow aliases to same id on different bases, too, unless we can prove they are not the same value.
> Source/JavaScriptCore/dfg/DFGAliasTracker.h:123 > + if (possibleAlias.child1() == node.child1()
This seems to only shoot down candidates for alias if they have the same base in the graph, but not if they have different bases. But different bases may refer to the same object. e.g. this will correctly prevent aliasing here (the two reads of a.y may read different values due to the assignment of b): function f1(a,b) { var x = a.y; a.y = b; return x + a.y; } however I think this will fail on the following: function f2(a,b,c) { var x = a.y; b.y = c; return x + a.y; } This time we won't detect that the write to b.y aliases a.y, so the assignment won't clear the alias & if the function is called with the same the object as a & b, then the latter read of a.y will incorrectly alias the original value rather than c. I think we need to shoot down aliases in all cases where the identifier matches?
> Source/JavaScriptCore/dfg/DFGJITCompiler.h:57 > +enum CompilerKind { Speculative, NonSpeculative, EitherCompiler };
JITCodeGenerator already has a member called m_isSpeculative, I don't think we need both this & the CompilerKind enum. It is probably better to use your enum since it is clearer & more descriptive, so I'd replace the member bool with a CompilerKind. But I think we do need this to be a member in some cases, so I think you can remove passing CompilerKind as an augment to function on JITCompiler in a number of cases, and just use the member instead. The key thing here is that we should unify these; we shouldn't have two ways of doing this.
Filip Pizlo
Comment 7
2011-07-29 16:32:37 PDT
(In reply to
comment #6
)
> (From update of
attachment 102228
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=102228&action=review
> > I think we need to blow aliases to same id on different bases, too, unless we can prove they are not the same value. > > > Source/JavaScriptCore/dfg/DFGAliasTracker.h:123 > > + if (possibleAlias.child1() == node.child1() > > This seems to only shoot down candidates for alias if they have the same base in the graph, but not if they have different bases. But different bases may refer to the same object. > e.g. this will correctly prevent aliasing here (the two reads of a.y may read different values due to the assignment of b): > function f1(a,b) { var x = a.y; a.y = b; return x + a.y; } > however I think this will fail on the following: > function f2(a,b,c) { var x = a.y; b.y = c; return x + a.y; } > This time we won't detect that the write to b.y aliases a.y, so the assignment won't clear the alias & if the function is called with the same the object as a & b, then the latter read of a.y will incorrectly alias the original value rather than c. > > I think we need to shoot down aliases in all cases where the identifier matches? > > > Source/JavaScriptCore/dfg/DFGJITCompiler.h:57 > > +enum CompilerKind { Speculative, NonSpeculative, EitherCompiler }; > > JITCodeGenerator already has a member called m_isSpeculative, I don't think we need both this & the CompilerKind enum. > It is probably better to use your enum since it is clearer & more descriptive, so I'd replace the member bool with a CompilerKind. > But I think we do need this to be a member in some cases, so I think you can remove passing CompilerKind as an augment to function on JITCompiler in a number of cases, and just use the member instead. > > The key thing here is that we should unify these; we shouldn't have two ways of doing this.
Gosh, good catch on both counts! My bad, I'll fix that.
Gavin Barraclough
Comment 8
2011-07-29 16:41:34 PDT
Oliver, could you eyeball the runtime changes to JSObject etc in this patch? Let me summarize. We need new get/put methods that will not cause side effects (e.g. call getter/setters), that can be used from the speculative path and relied on not to cause arbitrary code execution. Filip has added a putLimitedSideEffect methods which will only write to regular properties on instances of the JSFinalObject class. This seems safe. getNoSideEffect is a little more subtle. We've prohibited API objects (since they can do anything!) via the newly added propertyAccessesMayCauseArbitrarySideEffects() check. Otherwise, this patch will walk the proto chain calling fastGetOwnPropertySlot. Once it has the property slot it calls a new getValueNoSideEffect(), which won't call getters on it. Does this sound safe to you? Do we need guard against any objects in WebCore triggering arbitrary code execution from within a getOwnPropertySlot?
Oliver Hunt
Comment 9
2011-07-29 17:13:38 PDT
(In reply to
comment #8
)
> Oliver, could you eyeball the runtime changes to JSObject etc in this patch? > > Let me summarize. We need new get/put methods that will not cause side effects (e.g. call getter/setters), that can be used from the speculative path and relied on not to cause arbitrary code execution. > > Filip has added a putLimitedSideEffect methods which will only write to regular properties on instances of the JSFinalObject class. This seems safe. > > getNoSideEffect is a little more subtle. We've prohibited API objects (since they can do anything!) via the newly added propertyAccessesMayCauseArbitrarySideEffects() check. Otherwise, this patch will walk the proto chain calling fastGetOwnPropertySlot. Once it has the property slot it calls a new getValueNoSideEffect(), which won't call getters on it. Does this sound safe to you? Do we need guard against any objects in WebCore triggering arbitrary code execution from within a getOwnPropertySlot?
There are a reasonable number of objects in webcore that override getOwnPropertySlot, some of them have side effects on the _get_, most notable they may throw exceptions due to same origin violations. I believe the side-effect free lookup should do an explicit check for the overridesGetOwnPropertySlot() flag. propertyAccessesMayCauseArbitrarySideEffects seems very fragile as it is essentially a blacklist, and historically blacklist based filtering has been problematic for us. We're better off defaulting to property access being unsafe, and then opting in to this optimisation on a case by case basis (this only applies to classes that set overridesGetOwnPropertySlot). TLDR; this code is currently unsafe, there are a number of objects in the DOM where getOwnPropertySlot has immediate side effects
Filip Pizlo
Comment 10
2011-07-29 17:16:27 PDT
(In reply to
comment #9
)
> (In reply to
comment #8
) > > Oliver, could you eyeball the runtime changes to JSObject etc in this patch? > > > > Let me summarize. We need new get/put methods that will not cause side effects (e.g. call getter/setters), that can be used from the speculative path and relied on not to cause arbitrary code execution. > > > > Filip has added a putLimitedSideEffect methods which will only write to regular properties on instances of the JSFinalObject class. This seems safe. > > > > getNoSideEffect is a little more subtle. We've prohibited API objects (since they can do anything!) via the newly added propertyAccessesMayCauseArbitrarySideEffects() check. Otherwise, this patch will walk the proto chain calling fastGetOwnPropertySlot. Once it has the property slot it calls a new getValueNoSideEffect(), which won't call getters on it. Does this sound safe to you? Do we need guard against any objects in WebCore triggering arbitrary code execution from within a getOwnPropertySlot? > > There are a reasonable number of objects in webcore that override getOwnPropertySlot, some of them have side effects on the _get_, most notable they may throw exceptions due to same origin violations. > > I believe the side-effect free lookup should do an explicit check for the overridesGetOwnPropertySlot() flag. propertyAccessesMayCauseArbitrarySideEffects seems very fragile as it is essentially a blacklist, and historically blacklist based filtering has been problematic for us. We're better off defaulting to property access being unsafe, and then opting in to this optimisation on a case by case basis (this only applies to classes that set overridesGetOwnPropertySlot). > > TLDR; this code is currently unsafe, there are a number of objects in the DOM where getOwnPropertySlot has immediate side effects
Is this summary true even if exceptions are fine? By "no side effect" we mean that getOwnPropertySlot() will not modify the heap in some arbitrary way prior to returning. And by modifying the heap we specifically mean: modify properties that don't involve getters (custom or not).
Oliver Hunt
Comment 11
2011-07-29 17:25:34 PDT
(In reply to
comment #10
)
> (In reply to
comment #9
) > > (In reply to
comment #8
) > > > Oliver, could you eyeball the runtime changes to JSObject etc in this patch? > > > > > > Let me summarize. We need new get/put methods that will not cause side effects (e.g. call getter/setters), that can be used from the speculative path and relied on not to cause arbitrary code execution. > > > > > > Filip has added a putLimitedSideEffect methods which will only write to regular properties on instances of the JSFinalObject class. This seems safe. > > > > > > getNoSideEffect is a little more subtle. We've prohibited API objects (since they can do anything!) via the newly added propertyAccessesMayCauseArbitrarySideEffects() check. Otherwise, this patch will walk the proto chain calling fastGetOwnPropertySlot. Once it has the property slot it calls a new getValueNoSideEffect(), which won't call getters on it. Does this sound safe to you? Do we need guard against any objects in WebCore triggering arbitrary code execution from within a getOwnPropertySlot? > > > > There are a reasonable number of objects in webcore that override getOwnPropertySlot, some of them have side effects on the _get_, most notable they may throw exceptions due to same origin violations. > > > > I believe the side-effect free lookup should do an explicit check for the overridesGetOwnPropertySlot() flag. propertyAccessesMayCauseArbitrarySideEffects seems very fragile as it is essentially a blacklist, and historically blacklist based filtering has been problematic for us. We're better off defaulting to property access being unsafe, and then opting in to this optimisation on a case by case basis (this only applies to classes that set overridesGetOwnPropertySlot). > > > > TLDR; this code is currently unsafe, there are a number of objects in the DOM where getOwnPropertySlot has immediate side effects > > Is this summary true even if exceptions are fine? By "no side effect" we mean that getOwnPropertySlot() will not modify the heap in some arbitrary way prior to returning. And by modifying the heap we specifically mean: modify properties that don't involve getters (custom or not).
My point was that you're relying on _all_ code conforming to an invariant we can't enforce statically at compile time. If you were okay with exceptions being thrown you'd need to ensure you always cleared the exception slot. I also just realised that getOwnPropertySlot on a JSFunction can modify the object among other things -- it should not be observable that the change has happened, but it does modify the object.
Filip Pizlo
Comment 12
2011-07-29 23:50:01 PDT
> My point was that you're relying on _all_ code conforming to an invariant we can't enforce statically at compile time. If you were okay with exceptions being thrown you'd need to ensure you always cleared the exception slot.
The latter part is easy, the former comes down to a question of risk/reward. This patch wins us maybe 1%, and that's in an idealized fantasy world that involves the above-posted incorrect patch. So my feeling is to table this and revisit later (or never), especially given that we have other, bigger things, to optimize. Gavin, do you concur? And yeah, I have thought about making this an opt-in rather than opt-out speculation, where for example we only rely on GetById on JSFinalObject being free of side effects. This scares me as well because it would mean that any GetById on any non-JSFinalObject would currently knock us off the speculative path. That's not good, given that this is only a 1% win *in the idealized case*, and the non-speculative path is known to be more than 1% slower than the speculative path.
> I also just realised that getOwnPropertySlot on a JSFunction can modify the object among other things -- it should not be observable that the change has happened, but it does modify the object.
Yeah, changes in general are OK - but changes that are observable with GetById are not OK.
Sam Weinig
Comment 13
2011-08-11 15:26:02 PDT
I don't think we are going to do this. We can revisit some other time.
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