[interpreter] Optimize strict equal boolean
For strict equal boolean literal like "a===true" or "a===false", we could generate TestReferenceEqual rather than TestStrictEqual. And in `execution_result()->IsTest()` case, we could directly emit JumpIfTrue/JumpIfFalse. E.g. ``` a === true ``` Generated Bytecode From: ``` LdaGlobal Star1 LdaTrue TestEqualStrict ``` To: ``` LdaGlobal Star1 LdaTrue TestReferenceEqual ``` E.g. ``` if (a === true) ``` Generated Bytecode From: ``` LdaGlobal Star1 LdaTrue TestEqualStrict JumpIfFalse ``` To ``` LdaGlobal JumpIfTrue Jump ``` Bug: v8:6403 Change-Id: Ieaca147acd2d523ac0d2466e7861afb2d29a1310 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3568923 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: 王澳 <wangao.james@bytedance.com> Cr-Commit-Position: refs/heads/main@{#79935}
This commit is contained in:
parent
4c29cf1b78
commit
62632c0805
@ -103,6 +103,10 @@ bool Expression::IsNullLiteral() const {
|
||||
return IsLiteral() && AsLiteral()->type() == Literal::kNull;
|
||||
}
|
||||
|
||||
bool Expression::IsBooleanLiteral() const {
|
||||
return IsLiteral() && AsLiteral()->type() == Literal::kBoolean;
|
||||
}
|
||||
|
||||
bool Expression::IsTheHoleLiteral() const {
|
||||
return IsLiteral() && AsLiteral()->type() == Literal::kTheHole;
|
||||
}
|
||||
@ -892,6 +896,24 @@ static bool IsVoidOfLiteral(Expression* expr) {
|
||||
maybe_unary->expression()->IsLiteral();
|
||||
}
|
||||
|
||||
static bool MatchLiteralStrictCompareBoolean(Expression* left, Token::Value op,
|
||||
Expression* right,
|
||||
Expression** expr,
|
||||
Literal** literal) {
|
||||
if (left->IsBooleanLiteral() && op == Token::EQ_STRICT) {
|
||||
*expr = right;
|
||||
*literal = left->AsLiteral();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompareOperation::IsLiteralStrictCompareBoolean(Expression** expr,
|
||||
Literal** literal) {
|
||||
return MatchLiteralStrictCompareBoolean(left_, op(), right_, expr, literal) ||
|
||||
MatchLiteralStrictCompareBoolean(right_, op(), left_, expr, literal);
|
||||
}
|
||||
|
||||
// Check for the pattern: void <literal> equals <expression> or
|
||||
// undefined equals <expression>
|
||||
static bool MatchLiteralCompareUndefined(Expression* left, Token::Value op,
|
||||
|
@ -236,6 +236,8 @@ class Expression : public AstNode {
|
||||
// True iff the expression is the null literal.
|
||||
bool IsNullLiteral() const;
|
||||
|
||||
bool IsBooleanLiteral() const;
|
||||
|
||||
// True iff the expression is the hole literal.
|
||||
bool IsTheHoleLiteral() const;
|
||||
|
||||
@ -955,6 +957,11 @@ class Literal final : public Expression {
|
||||
return Smi::FromInt(smi_);
|
||||
}
|
||||
|
||||
bool AsBooleanLiteral() const {
|
||||
DCHECK_EQ(kBoolean, type());
|
||||
return boolean_;
|
||||
}
|
||||
|
||||
// Returns true if literal represents a Number.
|
||||
bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; }
|
||||
double AsNumber() const {
|
||||
@ -1963,6 +1970,7 @@ class CompareOperation final : public Expression {
|
||||
|
||||
// Match special cases.
|
||||
bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
|
||||
bool IsLiteralStrictCompareBoolean(Expression** expr, Literal** literal);
|
||||
bool IsLiteralCompareUndefined(Expression** expr);
|
||||
bool IsLiteralCompareNull(Expression** expr);
|
||||
|
||||
|
@ -3977,19 +3977,24 @@ void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfFalse() {
|
||||
NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
|
||||
Node* accumulator = environment()->LookupAccumulator();
|
||||
Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
|
||||
jsgraph()->FalseConstant());
|
||||
NewBranch(condition, BranchHint::kNone);
|
||||
{
|
||||
SubEnvironment sub_environment(this);
|
||||
NewIfFalse();
|
||||
NewIfTrue();
|
||||
environment()->BindAccumulator(jsgraph()->FalseConstant());
|
||||
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
|
||||
}
|
||||
NewIfTrue();
|
||||
environment()->BindAccumulator(jsgraph()->TrueConstant());
|
||||
NewIfFalse();
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfTrue() {
|
||||
NewBranch(environment()->LookupAccumulator(), BranchHint::kNone);
|
||||
Node* accumulator = environment()->LookupAccumulator();
|
||||
Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
|
||||
jsgraph()->TrueConstant());
|
||||
NewBranch(condition, BranchHint::kNone);
|
||||
{
|
||||
SubEnvironment sub_environment(this);
|
||||
NewIfTrue();
|
||||
@ -3997,7 +4002,6 @@ void BytecodeGraphBuilder::BuildJumpIfTrue() {
|
||||
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
|
||||
}
|
||||
NewIfFalse();
|
||||
environment()->BindAccumulator(jsgraph()->FalseConstant());
|
||||
}
|
||||
|
||||
void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
|
||||
|
@ -6157,6 +6157,29 @@ void BytecodeGenerator::BuildLiteralCompareNil(
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeGenerator::BuildLiteralStrictCompareBoolean(Literal* literal) {
|
||||
DCHECK(literal->IsBooleanLiteral());
|
||||
if (execution_result()->IsTest()) {
|
||||
TestResultScope* test_result = execution_result()->AsTest();
|
||||
if (literal->AsBooleanLiteral()) {
|
||||
builder()->JumpIfTrue(ToBooleanMode::kAlreadyBoolean,
|
||||
test_result->NewThenLabel());
|
||||
} else {
|
||||
builder()->JumpIfFalse(ToBooleanMode::kAlreadyBoolean,
|
||||
test_result->NewThenLabel());
|
||||
}
|
||||
if (test_result->fallthrough() != TestFallthrough::kElse) {
|
||||
builder()->Jump(test_result->NewElseLabel());
|
||||
}
|
||||
test_result->SetResultConsumedByTest();
|
||||
} else {
|
||||
Register result = register_allocator()->NewRegister();
|
||||
builder()->StoreAccumulatorInRegister(result);
|
||||
builder()->LoadBoolean(literal->AsBooleanLiteral());
|
||||
builder()->CompareReference(result);
|
||||
}
|
||||
}
|
||||
|
||||
void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
Expression* sub_expr;
|
||||
Literal* literal;
|
||||
@ -6172,6 +6195,11 @@ void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
||||
} else {
|
||||
builder()->CompareTypeOf(literal_flag);
|
||||
}
|
||||
} else if (expr->IsLiteralStrictCompareBoolean(&sub_expr, &literal)) {
|
||||
DCHECK(expr->op() == Token::EQ_STRICT);
|
||||
VisitForAccumulatorValue(sub_expr);
|
||||
builder()->SetExpressionPosition(expr);
|
||||
BuildLiteralStrictCompareBoolean(literal);
|
||||
} else if (expr->IsLiteralCompareUndefined(&sub_expr)) {
|
||||
VisitForAccumulatorValue(sub_expr);
|
||||
builder()->SetExpressionPosition(expr);
|
||||
|
@ -263,6 +263,7 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
||||
LookupHoistingMode lookup_hoisting_mode = LookupHoistingMode::kNormal);
|
||||
void BuildLiteralCompareNil(Token::Value compare_op,
|
||||
BytecodeArrayBuilder::NilValue nil);
|
||||
void BuildLiteralStrictCompareBoolean(Literal* literal);
|
||||
void BuildReturn(int source_position);
|
||||
void BuildAsyncReturn(int source_position);
|
||||
void BuildAsyncGeneratorReturn();
|
||||
|
@ -1915,7 +1915,6 @@ IGNITION_HANDLER(JumpConstant, InterpreterAssembler) {
|
||||
// will misbehave if passed arbitrary input values.
|
||||
IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
|
||||
TNode<Object> accumulator = GetAccumulator();
|
||||
CSA_DCHECK(this, IsBoolean(CAST(accumulator)));
|
||||
JumpIfTaggedEqual(accumulator, TrueConstant(), 0);
|
||||
}
|
||||
|
||||
@ -1926,7 +1925,6 @@ IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) {
|
||||
// and will misbehave if passed arbitrary input values.
|
||||
IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
|
||||
TNode<Object> accumulator = GetAccumulator();
|
||||
CSA_DCHECK(this, IsBoolean(CAST(accumulator)));
|
||||
JumpIfTaggedEqualConstant(accumulator, TrueConstant(), 0);
|
||||
}
|
||||
|
||||
@ -1937,7 +1935,6 @@ IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) {
|
||||
// will misbehave if passed arbitrary input values.
|
||||
IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
|
||||
TNode<Object> accumulator = GetAccumulator();
|
||||
CSA_DCHECK(this, IsBoolean(CAST(accumulator)));
|
||||
JumpIfTaggedEqual(accumulator, FalseConstant(), 0);
|
||||
}
|
||||
|
||||
@ -1948,7 +1945,6 @@ IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) {
|
||||
// and will misbehave if passed arbitrary input values.
|
||||
IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) {
|
||||
TNode<Object> accumulator = GetAccumulator();
|
||||
CSA_DCHECK(this, IsBoolean(CAST(accumulator)));
|
||||
JumpIfTaggedEqualConstant(accumulator, FalseConstant(), 0);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,368 @@
|
||||
#
|
||||
# Autogenerated by generate-bytecode-expectations.
|
||||
#
|
||||
|
||||
---
|
||||
wrap: yes
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = 1;
|
||||
return a === true;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 7
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaSmi), I8(1),
|
||||
B(Star0),
|
||||
/* 45 S> */ B(LdaTrue),
|
||||
B(TestReferenceEqual), R(0),
|
||||
/* 63 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = true;
|
||||
return true === a;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 6
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaTrue),
|
||||
B(Star0),
|
||||
/* 48 S> */ B(LdaTrue),
|
||||
B(TestReferenceEqual), R(0),
|
||||
/* 66 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = false;
|
||||
return true !== a;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 7
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaFalse),
|
||||
B(Star0),
|
||||
/* 49 S> */ B(LdaTrue),
|
||||
B(TestReferenceEqual), R(0),
|
||||
/* 61 E> */ B(LogicalNot),
|
||||
/* 67 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = 1;
|
||||
return true === a ? 1 : 2;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 14
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaSmi), I8(1),
|
||||
B(Star0),
|
||||
/* 45 S> */ B(JumpIfTrue), U8(4),
|
||||
B(Jump), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 71 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = true;
|
||||
return false === a ? 1 : 2;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 13
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaTrue),
|
||||
B(Star0),
|
||||
/* 48 S> */ B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 75 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = 1;
|
||||
return true !== a ? 1 : 2;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 12
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaSmi), I8(1),
|
||||
B(Star0),
|
||||
/* 45 S> */ B(JumpIfTrue), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 71 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = false;
|
||||
return false !== null ? 1 : 2;
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 12
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaFalse),
|
||||
B(Star0),
|
||||
/* 49 S> */ B(LdaNull),
|
||||
B(JumpIfFalse), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
/* 79 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = 0;
|
||||
if (a !== true) {
|
||||
return 1;
|
||||
}
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 9
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaZero),
|
||||
B(Star0),
|
||||
/* 45 S> */ B(JumpIfTrue), U8(5),
|
||||
/* 65 S> */ B(LdaSmi), I8(1),
|
||||
/* 74 S> */ B(Return),
|
||||
B(LdaUndefined),
|
||||
/* 77 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
var a = true;
|
||||
var b = 0;
|
||||
while (a !== true) {
|
||||
b++;
|
||||
}
|
||||
"
|
||||
frame size: 2
|
||||
parameter count: 1
|
||||
bytecode array length: 18
|
||||
bytecodes: [
|
||||
/* 42 S> */ B(LdaTrue),
|
||||
B(Star0),
|
||||
/* 56 S> */ B(LdaZero),
|
||||
B(Star1),
|
||||
/* 68 S> */ B(Ldar), R(0),
|
||||
B(JumpIfTrue), U8(10),
|
||||
/* 82 S> */ B(Ldar), R(1),
|
||||
B(Inc), U8(0),
|
||||
B(Star1),
|
||||
/* 59 E> */ B(JumpLoop), U8(9), I8(0),
|
||||
B(LdaUndefined),
|
||||
/* 89 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
(0 === true) ? 1 : 2;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 13
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaZero),
|
||||
B(JumpIfTrue), U8(4),
|
||||
B(Jump), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
B(LdaUndefined),
|
||||
/* 56 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
(0 !== true) ? 1 : 2;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 11
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaZero),
|
||||
B(JumpIfTrue), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
B(LdaUndefined),
|
||||
/* 56 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
(false === 0) ? 1 : 2;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 13
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaZero),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
B(LdaUndefined),
|
||||
/* 57 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
(0 === true || 0 === false) ? 1 : 2;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 16
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaZero),
|
||||
B(JumpIfTrue), U8(7),
|
||||
B(LdaZero),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(6),
|
||||
B(LdaSmi), I8(1),
|
||||
B(Jump), U8(4),
|
||||
B(LdaSmi), I8(2),
|
||||
B(LdaUndefined),
|
||||
/* 71 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
if (0 === true || 0 === false) return 1;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 13
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaZero),
|
||||
B(JumpIfTrue), U8(7),
|
||||
B(LdaZero),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(5),
|
||||
/* 65 S> */ B(LdaSmi), I8(1),
|
||||
/* 74 S> */ B(Return),
|
||||
B(LdaUndefined),
|
||||
/* 75 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
if (!('false' === false)) return 1;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 9
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaConstant), U8(0),
|
||||
B(JumpIfFalse), U8(5),
|
||||
/* 60 S> */ B(LdaSmi), I8(1),
|
||||
/* 69 S> */ B(Return),
|
||||
B(LdaUndefined),
|
||||
/* 70 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["false"],
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
if (!('false' !== false)) return 1;
|
||||
"
|
||||
frame size: 0
|
||||
parameter count: 1
|
||||
bytecode array length: 11
|
||||
bytecodes: [
|
||||
/* 34 S> */ B(LdaConstant), U8(0),
|
||||
B(JumpIfFalse), U8(4),
|
||||
B(Jump), U8(5),
|
||||
/* 60 S> */ B(LdaSmi), I8(1),
|
||||
/* 69 S> */ B(Return),
|
||||
B(LdaUndefined),
|
||||
/* 70 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
ONE_BYTE_INTERNALIZED_STRING_TYPE ["false"],
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
@ -1161,6 +1161,62 @@ TEST(CompareTypeOf) {
|
||||
LoadGolden("CompareTypeOf.golden")));
|
||||
}
|
||||
|
||||
TEST(CompareBoolean) {
|
||||
InitializedIgnitionHandleScope scope;
|
||||
BytecodeExpectationsPrinter printer(CcTest::isolate());
|
||||
|
||||
std::string snippets[] = {
|
||||
"var a = 1;\n"
|
||||
"return a === true;\n",
|
||||
|
||||
"var a = true;\n"
|
||||
"return true === a;\n",
|
||||
|
||||
"var a = false;\n"
|
||||
"return true !== a;\n",
|
||||
|
||||
"var a = 1;\n"
|
||||
"return true === a ? 1 : 2;\n",
|
||||
|
||||
"var a = true;\n"
|
||||
"return false === a ? 1 : 2;\n",
|
||||
|
||||
"var a = 1;\n"
|
||||
"return true !== a ? 1 : 2;\n",
|
||||
|
||||
"var a = false;\n"
|
||||
"return false !== null ? 1 : 2;\n",
|
||||
|
||||
"var a = 0;\n"
|
||||
"if (a !== true) {\n"
|
||||
" return 1;\n"
|
||||
"}\n",
|
||||
|
||||
"var a = true;\n"
|
||||
"var b = 0;\n"
|
||||
"while (a !== true) {\n"
|
||||
" b++;\n"
|
||||
"}\n",
|
||||
|
||||
"(0 === true) ? 1 : 2;\n",
|
||||
|
||||
"(0 !== true) ? 1 : 2;\n",
|
||||
|
||||
"(false === 0) ? 1 : 2;\n",
|
||||
|
||||
"(0 === true || 0 === false) ? 1 : 2;\n",
|
||||
|
||||
"if (0 === true || 0 === false) return 1;\n",
|
||||
|
||||
"if (!('false' === false)) return 1;\n",
|
||||
|
||||
"if (!('false' !== false)) return 1;\n",
|
||||
};
|
||||
|
||||
CHECK(CompareTexts(BuildActual(printer, snippets),
|
||||
LoadGolden("CompareBoolean.golden")));
|
||||
}
|
||||
|
||||
TEST(CompareNil) {
|
||||
InitializedIgnitionHandleScope scope;
|
||||
BytecodeExpectationsPrinter printer(CcTest::isolate());
|
||||
|
@ -16,6 +16,7 @@ addBenchmark('Number-StrictEquals-False', NumberStrictEqualsFalse);
|
||||
addBenchmark('String-StrictEquals-True', StringStrictEqualsTrue);
|
||||
addBenchmark('String-StrictEquals-False', StringStrictEqualsFalse);
|
||||
addBenchmark('SmiString-StrictEquals', MixedStrictEquals);
|
||||
addBenchmark('Boolean-StrictEquals', BooleanStrictEquals);
|
||||
addBenchmark('Smi-Equals-True', SmiEqualsTrue);
|
||||
addBenchmark('Smi-Equals-False', SmiEqualsFalse);
|
||||
addBenchmark('Number-Equals-True', NumberEqualsTrue);
|
||||
@ -46,6 +47,113 @@ function strictEquals(a, b) {
|
||||
}
|
||||
}
|
||||
|
||||
function strictEqualsBoolean(a) {
|
||||
var ret;
|
||||
for (var i = 0; i < 1000; ++i) {
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === true) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
if (a === false) ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function equals(a, b) {
|
||||
for (var i = 0; i < 1000; ++i) {
|
||||
a == b; a == b; a == b; a == b; a == b; a == b; a == b; a == b; a == b; a == b;
|
||||
@ -104,6 +212,12 @@ function StringStrictEqualsTrue() {
|
||||
strictEquals("abc", "abc");
|
||||
}
|
||||
|
||||
function BooleanStrictEquals() {
|
||||
strictEqualsBoolean("a");
|
||||
strictEqualsBoolean(true);
|
||||
strictEqualsBoolean(false);
|
||||
}
|
||||
|
||||
function MixedStrictEquals() {
|
||||
strictEquals(10, "10");
|
||||
}
|
||||
|
@ -318,6 +318,7 @@
|
||||
{"name": "String-StrictEquals-True"},
|
||||
{"name": "String-StrictEquals-False"},
|
||||
{"name": "SmiString-StrictEquals"},
|
||||
{"name": "Boolean-StrictEquals"},
|
||||
{"name": "Smi-Equals-True"},
|
||||
{"name": "Smi-Equals-False"},
|
||||
{"name": "Number-Equals-True"},
|
||||
|
Loading…
Reference in New Issue
Block a user