| 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
|
|
|