Bug 966665. Don't DCE DOM method calls and getters that can throw exceptions. r=jandem

This commit is contained in:
Boris Zbarsky 2014-02-03 11:04:06 -05:00
parent b4b3e1de20
commit 3c296f449e
4 changed files with 55 additions and 8 deletions

View File

@ -32,5 +32,6 @@ support-files =
[test_namedNoIndexed.html]
[test_queryInterface.html]
[test_sequence_wrapping.html]
[test_throwing_method_noDCE.html]
[test_treat_non_object_as_null.html]
[test_traceProtos.html]

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test that we don't DCE functions that can throw</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
function test(root) {
var threw = false;
try {
root.querySelectorAll("");
} catch(e){ threw = true; };
// Hot loop to make sure the JIT heuristics ion-compile this function even
// though it's throwing exceptions (which would normally make us back off
// of ion compilation).
for (var i=0; i<1500; i++) {}
return threw;
}
var threw = false;
var el = document.createElement("div");
for (var i=0; i<200; i++)
threw = test(el);
assert_true(threw);
}, "Shouldn't optimize away throwing functions");
</script>

View File

@ -672,10 +672,7 @@ MCall::New(TempAllocator &alloc, JSFunction *target, size_t maxArgc, size_t numA
AliasSet
MCallDOMNative::getAliasSet() const
{
JS_ASSERT(getSingleTarget() && getSingleTarget()->isNative());
const JSJitInfo *jitInfo = getSingleTarget()->jitInfo();
JS_ASSERT(jitInfo);
const JSJitInfo *jitInfo = getJitInfo();
JS_ASSERT(jitInfo->aliasSet() != JSJitInfo::AliasNone);
// If we don't know anything about the types of our arguments, we have to
@ -723,10 +720,7 @@ MCallDOMNative::computeMovable()
// We are movable if the jitinfo says we can be and if we're also not
// effectful. The jitinfo can't check for the latter, since it depends on
// the types of our arguments.
JS_ASSERT(getSingleTarget() && getSingleTarget()->isNative());
const JSJitInfo *jitInfo = getSingleTarget()->jitInfo();
JS_ASSERT(jitInfo);
const JSJitInfo *jitInfo = getJitInfo();
JS_ASSERT_IF(jitInfo->isMovable,
jitInfo->aliasSet() != JSJitInfo::AliasEverything);
@ -770,6 +764,17 @@ MCallDOMNative::congruentTo(MDefinition *ins) const
return true;
}
const JSJitInfo *
MCallDOMNative::getJitInfo() const
{
JS_ASSERT(getSingleTarget() && getSingleTarget()->isNative());
const JSJitInfo *jitInfo = getSingleTarget()->jitInfo();
JS_ASSERT(jitInfo);
return jitInfo;
}
MApplyArgs *
MApplyArgs::New(TempAllocator &alloc, JSFunction *target, MDefinition *fun, MDefinition *argc,
MDefinition *self)

View File

@ -1954,11 +1954,20 @@ class MCallDOMNative : public MCall
MCallDOMNative(JSFunction *target, uint32_t numActualArgs)
: MCall(target, numActualArgs, false)
{
// If our jitinfo is not marked movable, that means that our C++
// implementation is fallible or that we have no hope of ever doing the
// sort of argument analysis that would allow us to detemine that we're
// side-effect-free. In the latter case we wouldn't get DCEd no matter
// what, but for the former case we have to explicitly say that we can't
// be DCEd.
if (!getJitInfo()->isMovable)
setGuard();
}
friend MCall *MCall::New(TempAllocator &alloc, JSFunction *target, size_t maxArgc,
size_t numActualArgs, bool construct, bool isDOMCall);
const JSJitInfo *getJitInfo() const;
public:
virtual AliasSet getAliasSet() const MOZ_OVERRIDE;
@ -8032,6 +8041,11 @@ class MGetDOMProperty
if (isDomMovable()) {
JS_ASSERT(jitinfo->aliasSet() != JSJitInfo::AliasEverything);
setMovable();
} else {
// If we're not movable, that means we shouldn't be DCEd either,
// because we might throw an exception when called, and getting rid
// of that is observable.
setGuard();
}
setResultType(MIRType_Value);