author | Hannes Verschore <hv1989@gmail.com> |
Sat, 28 Feb 2015 01:30:38 +0100 | |
changeset 231227 | 14df9078d7a7b0f44b3c4260a2ae87972b62164d |
parent 231226 | 928ec762c672961919983ccc7ef7d642fe83313c |
child 231228 | 68c6f7e33f1e5479be8d45fa43e142eb90c9b53d |
push id | 56210 |
push user | hv1989@gmail.com |
push date | Sat, 28 Feb 2015 00:37:44 +0000 |
treeherder | mozilla-inbound@490afdad9ba1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 994016 |
milestone | 39.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug994016.js @@ -0,0 +1,48 @@ + +function test(x) { + return typeof x != "object" +} + +var obj = {}; +var func = function() {}; + +assertEq(test(""), true) +assertEq(test(""), true) +assertEq(test(1), true) +assertEq(test(1), true) +assertEq(test(1.5), true) +assertEq(test(1.5), true) +assertEq(test(undefined), true) +assertEq(test(undefined), true) +assertEq(test(func), true) +assertEq(test(func), true) + +function test2(x) { + return typeof x != "string" +} + +assertEq(test2(1), true) +assertEq(test2(1), true) +assertEq(test2(1.5), true) +assertEq(test2(1.5), true) +assertEq(test2(undefined), true) +assertEq(test2(undefined), true) +assertEq(test2(func), true) +assertEq(test2(func), true) +assertEq(test2(obj), true) +assertEq(test2(obj), true) + +function test3(x) { + return typeof x != "undefined" +} + +assertEq(test3(1), true) +assertEq(test3(1), true) +assertEq(test3(1.5), true) +assertEq(test3(1.5), true) +assertEq(test3(func), true) +assertEq(test3(func), true) +assertEq(test3(obj), true) +assertEq(test3(obj), true) +assertEq(test(""), true) +assertEq(test(""), true)
--- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2810,16 +2810,17 @@ MTypeOf::foldsTo(TempAllocator &alloc) // Note: we can't use input->type() here, type analysis has // boxed the input. MOZ_ASSERT(input()->type() == MIRType_Value); JSType type; switch (inputType()) { case MIRType_Double: + case MIRType_Float32: case MIRType_Int32: type = JSTYPE_NUMBER; break; case MIRType_String: type = JSTYPE_STRING; break; case MIRType_Symbol: type = JSTYPE_SYMBOL; @@ -3270,23 +3271,94 @@ MCompare::tryFoldEqualOperands(bool *res return false; } *result = (jsop() == JSOP_STRICTEQ); return true; } bool +MCompare::tryFoldTypeOf(bool *result) +{ + if (!lhs()->isTypeOf() && !rhs()->isTypeOf()) + return false; + if (!lhs()->isConstantValue() && !rhs()->isConstantValue()) + return false; + + MTypeOf *typeOf = lhs()->isTypeOf() ? lhs()->toTypeOf() : rhs()->toTypeOf(); + const Value *constant = lhs()->isConstantValue() ? lhs()->constantVp() : rhs()->constantVp(); + + if (!constant->isString()) + return false; + + if (jsop() != JSOP_STRICTEQ && jsop() != JSOP_STRICTNE && + jsop() != JSOP_EQ && jsop() != JSOP_NE) + { + return false; + } + + const JSAtomState &names = GetJitContext()->runtime->names(); + if (constant->toString() == TypeName(JSTYPE_VOID, names)) { + if (!typeOf->input()->mightBeType(MIRType_Undefined) && + !typeOf->inputMaybeCallableOrEmulatesUndefined()) + { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_BOOLEAN, names)) { + if (!typeOf->input()->mightBeType(MIRType_Boolean)) { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_NUMBER, names)) { + if (!typeOf->input()->mightBeType(MIRType_Int32) && + !typeOf->input()->mightBeType(MIRType_Float32) && + !typeOf->input()->mightBeType(MIRType_Double)) + { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_STRING, names)) { + if (!typeOf->input()->mightBeType(MIRType_String)) { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_SYMBOL, names)) { + if (!typeOf->input()->mightBeType(MIRType_Symbol)) { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) { + if (!typeOf->input()->mightBeType(MIRType_Object) && + !typeOf->input()->mightBeType(MIRType_Null)) + { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } else if (constant->toString() == TypeName(JSTYPE_FUNCTION, names)) { + if (!typeOf->inputMaybeCallableOrEmulatesUndefined()) { + *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); + return true; + } + } + + return false; +} + +bool MCompare::tryFold(bool *result) { JSOp op = jsop(); if (tryFoldEqualOperands(result)) return true; + if (tryFoldTypeOf(result)) + return true; + if (compareType_ == Compare_Null || compareType_ == Compare_Undefined) { // The LHS is the value we want to test against null or undefined. if (op == JSOP_STRICTEQ || op == JSOP_STRICTNE) { if (lhs()->type() == inputType()) { *result = (op == JSOP_STRICTEQ); return true; } if (!lhs()->mightBeType(inputType())) {
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -3992,16 +3992,17 @@ class MCompare return compareType_ == Compare_Float32; } # endif ALLOW_CLONE(MCompare) protected: bool tryFoldEqualOperands(bool *result); + bool tryFoldTypeOf(bool *result); bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE { if (!binaryCongruentTo(ins)) return false; return compareType() == ins->toCompare()->compareType() && jsop() == ins->toCompare()->jsop(); } };