Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(984)

Unified Diff: src/interpreter/bytecode-generator.cc

Issue 2795183002: [Interpreter] Move ToBoolean elision in BytecodeGenerator. (Closed)
Patch Set: tests Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-peephole-optimizer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 06f819e4a99c4cdf9580091c073d5a6bce6d074e..bfdc694892ad9e6599821effbffa603bd44a9f00 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -190,7 +190,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
Entry& entry = deferred_[i];
builder()->LoadLiteral(Smi::FromInt(entry.token));
builder()->CompareOperation(Token::EQ_STRICT, token_register_);
- dispatch.Case(static_cast<int>(i));
+ dispatch.Case(ToBooleanMode::kAlreadyBoolean, static_cast<int>(i));
}
dispatch.DefaultAt(static_cast<int>(deferred_.size()));
for (size_t i = 0; i < deferred_.size(); ++i) {
@@ -411,9 +411,10 @@ class BytecodeGenerator::ExpressionResultScope {
public:
ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
: generator_(generator),
- kind_(kind),
outer_(generator->execution_result()),
- allocator_(generator) {
+ allocator_(generator),
+ kind_(kind),
+ type_hint_(TypeHint::kAny) {
generator_->set_execution_result(this);
}
@@ -430,11 +431,20 @@ class BytecodeGenerator::ExpressionResultScope {
return reinterpret_cast<TestResultScope*>(this);
}
+ // Specify expression always returns a Boolean result value.
+ void SetResultIsBoolean() {
+ DCHECK(type_hint_ == TypeHint::kAny);
+ type_hint_ = TypeHint::kBoolean;
+ }
+
+ TypeHint type_hint() const { return type_hint_; }
+
private:
BytecodeGenerator* generator_;
- Expression::Context kind_;
ExpressionResultScope* outer_;
RegisterAllocationScope allocator_;
+ Expression::Context kind_;
+ TypeHint type_hint_;
DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
};
@@ -473,8 +483,7 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
void SetResultConsumedByTest() {
result_consumed_by_test_ = true;
}
-
- bool ResultConsumedByTest() { return result_consumed_by_test_; }
+ bool result_consumed_by_test() { return result_consumed_by_test_; }
BytecodeLabel* NewThenLabel() { return then_labels_->New(); }
BytecodeLabel* NewElseLabel() { return else_labels_->New(); }
@@ -794,7 +803,7 @@ void BytecodeGenerator::BuildIndexedJump(Register index, size_t start_index,
builder()
->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
.CompareOperation(Token::Value::EQ_STRICT, index)
- .JumpIfTrue(&(targets[i]));
+ .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &(targets[i]));
}
BuildAbort(BailoutReason::kInvalidJumpTableIndex);
}
@@ -828,7 +837,7 @@ void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
builder()
->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
.CompareOperation(Token::Value::EQ_STRICT, generator_state_)
- .JumpIfTrue(&not_resuming);
+ .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &not_resuming);
BuildIndexedJump(generator_state_, first_yield, stmt->suspend_count(),
generator_resume_points_);
builder()->Bind(&not_resuming);
@@ -1142,7 +1151,7 @@ void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
builder()->CompareOperation(
Token::Value::EQ_STRICT, tag,
feedback_index(clause->CompareOperationFeedbackSlot()));
- switch_builder.Case(i);
+ switch_builder.Case(ToBooleanMode::kAlreadyBoolean, i);
}
if (default_index >= 0) {
@@ -1344,7 +1353,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
VisitIterationHeader(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->each());
builder()->ForInContinue(index, cache_length);
- loop_builder.BreakIfFalse();
+ loop_builder.BreakIfFalse(ToBooleanMode::kAlreadyBoolean);
FeedbackSlot slot = stmt->ForInFeedbackSlot();
builder()->ForInNext(receiver, index, triple.Truncate(2),
feedback_index(slot));
@@ -1368,8 +1377,8 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
VisitIterationHeader(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->next_result());
VisitForEffect(stmt->next_result());
- VisitForAccumulatorValue(stmt->result_done());
- loop_builder.BreakIfTrue();
+ TypeHint type_hint = VisitForAccumulatorValue(stmt->result_done());
+ loop_builder.BreakIfTrue(ToBooleanModeFromTypeHint(type_hint));
VisitForEffect(stmt->assign_each());
VisitIterationBody(stmt, &loop_builder);
@@ -1562,7 +1571,7 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
builder()
->LoadLiteral(ast_string_constants()->prototype_string())
.CompareOperation(Token::Value::EQ_STRICT, key)
- .JumpIfFalse(&done)
+ .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done)
.CallRuntime(Runtime::kThrowStaticPrototypeError)
.Bind(&done);
}
@@ -1662,6 +1671,9 @@ void BytecodeGenerator::VisitLiteral(Literal* expr) {
if (!execution_result()->IsEffect()) {
const AstValue* raw_value = expr->raw_value();
builder()->LoadLiteral(raw_value);
+ if (raw_value->IsTrue() || raw_value->IsFalse()) {
+ execution_result()->SetResultIsBoolean();
+ }
}
}
@@ -2450,10 +2462,10 @@ void BytecodeGenerator::VisitSuspend(Suspend* expr) {
builder()
->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
.CompareOperation(Token::EQ_STRICT, resume_mode)
- .JumpIfTrue(&resume_with_next)
+ .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_next)
.LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow))
.CompareOperation(Token::EQ_STRICT, resume_mode)
- .JumpIfTrue(&resume_with_throw)
+ .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_throw)
.Jump(&resume_with_return);
builder()->Bind(&resume_with_return);
@@ -2814,9 +2826,11 @@ void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
test_result->inverted_fallthrough());
test_result->SetResultConsumedByTest();
} else {
- VisitForAccumulatorValue(expr->expression());
- builder()->LogicalNot();
+ TypeHint type_hint = VisitForAccumulatorValue(expr->expression());
+ builder()->LogicalNot(ToBooleanModeFromTypeHint(type_hint));
}
+ // Always returns a boolean value.
+ execution_result()->SetResultIsBoolean();
}
void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
@@ -3095,6 +3109,8 @@ void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
builder()->CompareOperation(expr->op(), lhs, feedback_index(slot));
}
}
+ // Always returns a boolean value.
+ execution_result()->SetResultIsBoolean();
}
void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
@@ -3229,8 +3245,8 @@ void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
VisitForAccumulatorValue(right);
} else {
BytecodeLabel end_label;
- VisitForAccumulatorValue(left);
- builder()->JumpIfTrue(&end_label);
+ TypeHint type_hint = VisitForAccumulatorValue(left);
+ builder()->JumpIfTrue(ToBooleanModeFromTypeHint(type_hint), &end_label);
VisitForAccumulatorValue(right);
builder()->Bind(&end_label);
}
@@ -3264,8 +3280,8 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
VisitForAccumulatorValue(right);
} else {
BytecodeLabel end_label;
- VisitForAccumulatorValue(left);
- builder()->JumpIfFalse(&end_label);
+ TypeHint type_hint = VisitForAccumulatorValue(left);
+ builder()->JumpIfFalse(ToBooleanModeFromTypeHint(type_hint), &end_label);
VisitForAccumulatorValue(right);
builder()->Bind(&end_label);
}
@@ -3485,9 +3501,11 @@ void BytecodeGenerator::VisitFunctionClosureForContext() {
}
// Visits the expression |expr| and places the result in the accumulator.
-void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
+BytecodeGenerator::TypeHint BytecodeGenerator::VisitForAccumulatorValue(
+ Expression* expr) {
ValueResultScope accumulator_scope(this);
Visit(expr);
+ return accumulator_scope.type_hint();
}
void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
@@ -3551,24 +3569,27 @@ void BytecodeGenerator::VisitForTest(Expression* expr,
BytecodeLabels* else_labels,
TestFallthrough fallthrough) {
bool result_consumed;
+ TypeHint type_hint;
{
// To make sure that all temporary registers are returned before generating
// jumps below, we ensure that the result scope is deleted before doing so.
// Dead registers might be materialized otherwise.
TestResultScope test_result(this, then_labels, else_labels, fallthrough);
Visit(expr);
- result_consumed = test_result.ResultConsumedByTest();
+ result_consumed = test_result.result_consumed_by_test();
+ type_hint = test_result.type_hint();
}
if (!result_consumed) {
+ ToBooleanMode mode(ToBooleanModeFromTypeHint(type_hint));
switch (fallthrough) {
case TestFallthrough::kThen:
- builder()->JumpIfFalse(else_labels->New());
+ builder()->JumpIfFalse(mode, else_labels->New());
break;
case TestFallthrough::kElse:
- builder()->JumpIfTrue(then_labels->New());
+ builder()->JumpIfTrue(mode, then_labels->New());
break;
case TestFallthrough::kNone:
- builder()->JumpIfTrue(then_labels->New());
+ builder()->JumpIfTrue(mode, then_labels->New());
builder()->Jump(else_labels->New());
}
}
@@ -3581,6 +3602,12 @@ void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
Visit(stmt);
}
+BytecodeArrayBuilder::ToBooleanMode
+BytecodeGenerator::ToBooleanModeFromTypeHint(TypeHint type_hint) {
+ return type_hint == TypeHint::kBoolean ? ToBooleanMode::kAlreadyBoolean
+ : ToBooleanMode::kConvertToBoolean;
+}
+
LanguageMode BytecodeGenerator::language_mode() const {
return current_scope()->language_mode();
}
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-peephole-optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698