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

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

Issue 2441543005: [full-codegen] Eliminate unnecessary hole checks for stores (Closed)
Patch Set: Merge and fix modules Created 4 years, 2 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') | no next file » | 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 84d8f8149330ceaf7814eafaad0e3502b99f6c2d..9ef9160582a27150fa1cda359dc9adc60a9e8c69 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -830,7 +830,8 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
if (variable->IsExport() && variable->binding_needs_init()) {
builder()->LoadTheHole();
BuildVariableAssignment(variable, Token::INIT,
- FeedbackVectorSlot::Invalid(), false);
+ FeedbackVectorSlot::Invalid(),
+ HoleCheckMode::kElided);
}
// Nothing to do for imports.
break;
@@ -850,7 +851,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
case VariableLocation::LOCAL: {
VisitForAccumulatorValue(decl->fun());
BuildVariableAssignment(variable, Token::INIT,
- FeedbackVectorSlot::Invalid(), false);
+ FeedbackVectorSlot::Invalid(),
+ HoleCheckMode::kElided);
break;
}
case VariableLocation::CONTEXT: {
@@ -875,7 +877,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
DCHECK(variable->IsExport());
VisitForAccumulatorValue(decl->fun());
BuildVariableAssignment(variable, Token::INIT,
- FeedbackVectorSlot::Invalid(), false);
+ FeedbackVectorSlot::Invalid(),
+ HoleCheckMode::kElided);
break;
}
}
@@ -895,7 +898,7 @@ void BytecodeGenerator::VisitModuleNamespaceImports() {
Variable* var = scope()->LookupLocal(entry->local_name);
DCHECK_NOT_NULL(var);
BuildVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid(),
- false);
+ HoleCheckMode::kElided);
}
}
@@ -1150,7 +1153,7 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr,
case VARIABLE: {
VariableProxy* proxy = expr->AsVariableProxy();
BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot,
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
break;
}
case NAMED_PROPERTY: {
@@ -1401,7 +1404,8 @@ void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
FeedbackVectorSlot slot = expr->NeedsProxySlot()
? expr->ProxySlot()
: FeedbackVectorSlot::Invalid();
- BuildVariableAssignment(proxy->var(), Token::INIT, slot, false);
+ BuildVariableAssignment(proxy->var(), Token::INIT, slot,
+ HoleCheckMode::kElided);
}
}
@@ -1776,12 +1780,12 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
builder()->SetExpressionPosition(proxy);
BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
}
void BytecodeGenerator::BuildVariableLoad(Variable* variable,
FeedbackVectorSlot slot,
- bool needs_hole_check,
+ HoleCheckMode hole_check_mode,
TypeofMode typeof_mode) {
switch (variable->location()) {
case VariableLocation::LOCAL: {
@@ -1790,7 +1794,9 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
// VisitForRegisterScope, in order to avoid register aliasing if
// subsequent expressions assign to the same variable.
builder()->LoadAccumulatorWithRegister(source);
- if (needs_hole_check) BuildThrowIfHole(variable->name());
+ if (hole_check_mode == HoleCheckMode::kRequired) {
+ BuildThrowIfHole(variable->name());
+ }
break;
}
case VariableLocation::PARAMETER: {
@@ -1801,7 +1807,9 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
// VisitForRegisterScope, in order to avoid register aliasing if
// subsequent expressions assign to the same variable.
builder()->LoadAccumulatorWithRegister(source);
- if (needs_hole_check) BuildThrowIfHole(variable->name());
+ if (hole_check_mode == HoleCheckMode::kRequired) {
+ BuildThrowIfHole(variable->name());
+ }
break;
}
case VariableLocation::UNALLOCATED: {
@@ -1820,7 +1828,9 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
}
builder()->LoadContextSlot(context_reg, variable->index(), depth);
- if (needs_hole_check) BuildThrowIfHole(variable->name());
+ if (hole_check_mode == HoleCheckMode::kRequired) {
+ BuildThrowIfHole(variable->name());
+ }
break;
}
case VariableLocation::LOOKUP: {
@@ -1831,7 +1841,9 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
execution_context()->ContextChainDepth(local_variable->scope());
builder()->LoadLookupContextSlot(variable->name(), typeof_mode,
local_variable->index(), depth);
- if (needs_hole_check) BuildThrowIfHole(variable->name());
+ if (hole_check_mode == HoleCheckMode::kRequired) {
+ BuildThrowIfHole(variable->name());
+ }
break;
}
case DYNAMIC_GLOBAL: {
@@ -1866,17 +1878,19 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
.StoreAccumulatorInRegister(args[1])
.CallRuntime(Runtime::kLoadModuleImport, args);
}
- if (needs_hole_check) BuildThrowIfHole(variable->name());
+ if (hole_check_mode == HoleCheckMode::kRequired) {
+ BuildThrowIfHole(variable->name());
+ }
break;
}
}
}
void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
- Variable* variable, FeedbackVectorSlot slot, bool needs_hole_check,
+ Variable* variable, FeedbackVectorSlot slot, HoleCheckMode hole_check_mode,
TypeofMode typeof_mode) {
ValueResultScope accumulator_result(this);
- BuildVariableLoad(variable, slot, needs_hole_check, typeof_mode);
+ BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode);
}
void BytecodeGenerator::BuildReturn() {
@@ -1948,7 +1962,7 @@ void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
Token::Value op,
FeedbackVectorSlot slot,
- bool needs_hole_check) {
+ HoleCheckMode hole_check_mode) {
VariableMode mode = variable->mode();
RegisterAllocationScope assignment_register_scope(this);
BytecodeLabel end_label;
@@ -1962,7 +1976,7 @@ void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
destination = Register(variable->index());
}
- if (needs_hole_check) {
+ if (hole_check_mode == HoleCheckMode::kRequired) {
// Load destination to check for hole.
Register value_temp = register_allocator()->NewRegister();
builder()
@@ -1997,7 +2011,7 @@ void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
context_reg = execution_context()->reg();
}
- if (needs_hole_check) {
+ if (hole_check_mode == HoleCheckMode::kRequired) {
// Load destination to check for hole.
Register value_temp = register_allocator()->NewRegister();
builder()
@@ -2043,7 +2057,7 @@ void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
->StoreAccumulatorInRegister(args[1])
.LoadLiteral(it->second->export_name->string())
.StoreAccumulatorInRegister(args[0]);
- if (needs_hole_check) {
+ if (hole_check_mode == HoleCheckMode::kRequired) {
builder()->CallRuntime(Runtime::kLoadModuleExport, args[0]);
BuildHoleCheckForVariableAssignment(variable, op);
}
@@ -2112,7 +2126,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
case VARIABLE: {
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
builder()->StoreAccumulatorInRegister(old_value);
break;
}
@@ -2165,7 +2179,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
// Is the value in the accumulator safe? Yes, but scary.
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), expr->op(), slot,
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
break;
}
case NAMED_PROPERTY:
@@ -2393,7 +2407,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
VariableProxy* proxy = callee_expr->AsVariableProxy();
BuildVariableLoadForAccumulatorValue(proxy->var(),
proxy->VariableFeedbackSlot(),
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
builder()->StoreAccumulatorInRegister(callee);
break;
}
@@ -2551,7 +2565,7 @@ void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
// perform a non-contextual load in case the operand is a variable proxy.
VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableLoadForAccumulatorValue(
- proxy->var(), proxy->VariableFeedbackSlot(), proxy->needs_hole_check(),
+ proxy->var(), proxy->VariableFeedbackSlot(), proxy->hole_check_mode(),
INSIDE_TYPEOF);
} else {
VisitForAccumulatorValue(expr->expression());
@@ -2678,7 +2692,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableLoadForAccumulatorValue(proxy->var(),
proxy->VariableFeedbackSlot(),
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
break;
}
case NAMED_PROPERTY: {
@@ -2743,7 +2757,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
case VARIABLE: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot,
- proxy->needs_hole_check());
+ proxy->hole_check_mode());
break;
}
case NAMED_PROPERTY: {
@@ -3036,7 +3050,8 @@ void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
: CreateArgumentsType::kMappedArguments;
builder()->CreateArguments(type);
BuildVariableAssignment(variable, Token::ASSIGN,
- FeedbackVectorSlot::Invalid(), false);
+ FeedbackVectorSlot::Invalid(),
+ HoleCheckMode::kElided);
}
void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
@@ -3047,7 +3062,7 @@ void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
builder()->CreateArguments(CreateArgumentsType::kRestParameter);
DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
BuildVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid(),
- false);
+ HoleCheckMode::kElided);
}
void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
@@ -3056,7 +3071,7 @@ void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
// Store the closure we were called with in the given variable.
builder()->LoadAccumulatorWithRegister(Register::function_closure());
BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
- false);
+ HoleCheckMode::kElided);
}
void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
@@ -3065,7 +3080,7 @@ void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
// Store the new target we were called with in the given variable.
builder()->LoadAccumulatorWithRegister(Register::new_target());
BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
- false);
+ HoleCheckMode::kElided);
// TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
// and we need to make sure {BytecodeRegisterOptimizer} flushes its state
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698