| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index fc5a4a4fa67c5a470aefee9b7dfe4b2d7600301e..3ac33039220292b6d165ef69d811fdfdfc17a470 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -829,8 +829,8 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| case VariableLocation::MODULE:
|
| if (variable->IsExport() && variable->binding_needs_init()) {
|
| builder()->LoadTheHole();
|
| - VisitVariableAssignment(variable, Token::INIT,
|
| - FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(variable, Token::INIT,
|
| + FeedbackVectorSlot::Invalid(), decl->proxy());
|
| }
|
| // Nothing to do for imports.
|
| break;
|
| @@ -849,8 +849,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| case VariableLocation::PARAMETER:
|
| case VariableLocation::LOCAL: {
|
| VisitForAccumulatorValue(decl->fun());
|
| - VisitVariableAssignment(variable, Token::INIT,
|
| - FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(variable, Token::INIT,
|
| + FeedbackVectorSlot::Invalid(), decl->proxy());
|
| break;
|
| }
|
| case VariableLocation::CONTEXT: {
|
| @@ -874,8 +874,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| DCHECK_EQ(variable->mode(), LET);
|
| DCHECK(variable->IsExport());
|
| VisitForAccumulatorValue(decl->fun());
|
| - VisitVariableAssignment(variable, Token::INIT,
|
| - FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(variable, Token::INIT,
|
| + FeedbackVectorSlot::Invalid(), decl->proxy());
|
| break;
|
| }
|
| }
|
| @@ -894,7 +894,7 @@ void BytecodeGenerator::VisitModuleNamespaceImports() {
|
| .CallRuntime(Runtime::kGetModuleNamespace, module_request);
|
| Variable* var = scope()->LookupLocal(entry->local_name);
|
| DCHECK_NOT_NULL(var);
|
| - VisitVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid());
|
| }
|
| }
|
|
|
| @@ -1147,8 +1147,8 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr,
|
| LhsKind assign_type = Property::GetAssignType(property);
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| - Variable* variable = expr->AsVariableProxy()->var();
|
| - VisitVariableAssignment(variable, Token::ASSIGN, slot);
|
| + VariableProxy* proxy = expr->AsVariableProxy();
|
| + BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot, proxy);
|
| break;
|
| }
|
| case NAMED_PROPERTY: {
|
| @@ -1395,11 +1395,11 @@ void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
|
| builder()->CallRuntime(Runtime::kToFastProperties, literal);
|
| // Assign to class variable.
|
| if (expr->class_variable_proxy() != nullptr) {
|
| - Variable* var = expr->class_variable_proxy()->var();
|
| + VariableProxy* proxy = expr->class_variable_proxy();
|
| FeedbackVectorSlot slot = expr->NeedsProxySlot()
|
| ? expr->ProxySlot()
|
| : FeedbackVectorSlot::Invalid();
|
| - VisitVariableAssignment(var, Token::INIT, slot);
|
| + BuildVariableAssignment(proxy->var(), Token::INIT, slot, proxy);
|
| }
|
| }
|
|
|
| @@ -1773,18 +1773,19 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
|
|
| void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
|
| builder()->SetExpressionPosition(proxy);
|
| - VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
|
| + BuildVariableLoad(proxy);
|
| }
|
|
|
| -void BytecodeGenerator::BuildHoleCheckForVariableLoad(Variable* variable) {
|
| - if (variable->binding_needs_init()) {
|
| - BuildThrowIfHole(variable->name());
|
| +void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableProxy* proxy) {
|
| + if (proxy->needs_hole_check()) {
|
| + BuildThrowIfHole(proxy->name());
|
| }
|
| }
|
|
|
| -void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| - FeedbackVectorSlot slot,
|
| +void BytecodeGenerator::BuildVariableLoad(VariableProxy* proxy,
|
| TypeofMode typeof_mode) {
|
| + Variable* variable = proxy->var();
|
| + FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
|
| switch (variable->location()) {
|
| case VariableLocation::LOCAL: {
|
| Register source(Register(variable->index()));
|
| @@ -1792,7 +1793,7 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| // VisitForRegisterScope, in order to avoid register aliasing if
|
| // subsequent expressions assign to the same variable.
|
| builder()->LoadAccumulatorWithRegister(source);
|
| - BuildHoleCheckForVariableLoad(variable);
|
| + BuildHoleCheckForVariableLoad(proxy);
|
| break;
|
| }
|
| case VariableLocation::PARAMETER: {
|
| @@ -1803,7 +1804,7 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| // VisitForRegisterScope, in order to avoid register aliasing if
|
| // subsequent expressions assign to the same variable.
|
| builder()->LoadAccumulatorWithRegister(source);
|
| - BuildHoleCheckForVariableLoad(variable);
|
| + BuildHoleCheckForVariableLoad(proxy);
|
| break;
|
| }
|
| case VariableLocation::UNALLOCATED: {
|
| @@ -1822,7 +1823,7 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| }
|
|
|
| builder()->LoadContextSlot(context_reg, variable->index(), depth);
|
| - BuildHoleCheckForVariableLoad(variable);
|
| + BuildHoleCheckForVariableLoad(proxy);
|
| break;
|
| }
|
| case VariableLocation::LOOKUP: {
|
| @@ -1833,7 +1834,7 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| execution_context()->ContextChainDepth(local_variable->scope());
|
| builder()->LoadLookupContextSlot(variable->name(), typeof_mode,
|
| local_variable->index(), depth);
|
| - BuildHoleCheckForVariableLoad(variable);
|
| + BuildHoleCheckForVariableLoad(proxy);
|
| break;
|
| }
|
| case DYNAMIC_GLOBAL: {
|
| @@ -1868,16 +1869,16 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| .StoreAccumulatorInRegister(args[1])
|
| .CallRuntime(Runtime::kLoadModuleImport, args);
|
| }
|
| - BuildHoleCheckForVariableLoad(variable);
|
| + BuildHoleCheckForVariableLoad(proxy);
|
| break;
|
| }
|
| }
|
| }
|
|
|
| -void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
|
| - Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
|
| +void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
|
| + VariableProxy* proxy, TypeofMode typeof_mode) {
|
| ValueResultScope accumulator_result(this);
|
| - VisitVariableLoad(variable, slot, typeof_mode);
|
| + BuildVariableLoad(proxy, typeof_mode);
|
| }
|
|
|
| void BytecodeGenerator::BuildReturn() {
|
| @@ -1946,15 +1947,16 @@ void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
|
| }
|
| }
|
|
|
| -void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| +void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
|
| Token::Value op,
|
| - FeedbackVectorSlot slot) {
|
| + FeedbackVectorSlot slot,
|
| + VariableProxy* proxy) {
|
| + DCHECK_IMPLIES(proxy != nullptr, variable == proxy->var());
|
| + DCHECK_IMPLIES(proxy == nullptr, !variable->binding_needs_init());
|
| + bool hole_check_required = proxy != nullptr && proxy->needs_hole_check();
|
| VariableMode mode = variable->mode();
|
| RegisterAllocationScope assignment_register_scope(this);
|
| BytecodeLabel end_label;
|
| - bool hole_check_required =
|
| - variable->binding_needs_init() &&
|
| - (op != Token::INIT || (mode == CONST && variable->is_this()));
|
| switch (variable->location()) {
|
| case VariableLocation::PARAMETER:
|
| case VariableLocation::LOCAL: {
|
| @@ -2108,7 +2110,7 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| VariableProxy* proxy = expr->target()->AsVariableProxy();
|
| - VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
|
| + BuildVariableLoad(proxy);
|
| builder()->StoreAccumulatorInRegister(old_value);
|
| break;
|
| }
|
| @@ -2157,10 +2159,10 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
|
| FeedbackVectorSlot slot = expr->AssignmentSlot();
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| - // TODO(oth): The VisitVariableAssignment() call is hard to reason about.
|
| + // TODO(oth): The BuildVariableAssignment() call is hard to reason about.
|
| // Is the value in the accumulator safe? Yes, but scary.
|
| - Variable* variable = expr->target()->AsVariableProxy()->var();
|
| - VisitVariableAssignment(variable, expr->op(), slot);
|
| + VariableProxy* proxy = expr->target()->AsVariableProxy();
|
| + BuildVariableAssignment(proxy->var(), expr->op(), slot, proxy);
|
| break;
|
| }
|
| case NAMED_PROPERTY:
|
| @@ -2386,8 +2388,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
|
| builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
|
| // Load callee as a global variable.
|
| VariableProxy* proxy = callee_expr->AsVariableProxy();
|
| - VisitVariableLoadForAccumulatorValue(proxy->var(),
|
| - proxy->VariableFeedbackSlot());
|
| + BuildVariableLoadForAccumulatorValue(proxy);
|
| builder()->StoreAccumulatorInRegister(callee);
|
| break;
|
| }
|
| @@ -2553,8 +2554,7 @@ void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
|
| // Typeof does not throw a reference error on global variables, hence we
|
| // perform a non-contextual load in case the operand is a variable proxy.
|
| VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
| - VisitVariableLoadForAccumulatorValue(
|
| - proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF);
|
| + BuildVariableLoadForAccumulatorValue(proxy, INSIDE_TYPEOF);
|
| } else {
|
| VisitForAccumulatorValue(expr->expression());
|
| }
|
| @@ -2678,8 +2678,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
| - VisitVariableLoadForAccumulatorValue(proxy->var(),
|
| - proxy->VariableFeedbackSlot());
|
| + BuildVariableLoadForAccumulatorValue(proxy);
|
| break;
|
| }
|
| case NAMED_PROPERTY: {
|
| @@ -2742,8 +2741,8 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| FeedbackVectorSlot feedback_slot = expr->CountSlot();
|
| switch (assign_type) {
|
| case VARIABLE: {
|
| - Variable* variable = expr->expression()->AsVariableProxy()->var();
|
| - VisitVariableAssignment(variable, expr->op(), feedback_slot);
|
| + VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
| + BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot, proxy);
|
| break;
|
| }
|
| case NAMED_PROPERTY: {
|
| @@ -3035,7 +3034,7 @@ void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
|
| ? CreateArgumentsType::kUnmappedArguments
|
| : CreateArgumentsType::kMappedArguments;
|
| builder()->CreateArguments(type);
|
| - VisitVariableAssignment(variable, Token::ASSIGN,
|
| + BuildVariableAssignment(variable, Token::ASSIGN,
|
| FeedbackVectorSlot::Invalid());
|
| }
|
|
|
| @@ -3046,7 +3045,7 @@ void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
|
| // variable.
|
| builder()->CreateArguments(CreateArgumentsType::kRestParameter);
|
| DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
|
| - VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid());
|
| }
|
|
|
| void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
|
| @@ -3054,7 +3053,7 @@ void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
|
|
|
| // Store the closure we were called with in the given variable.
|
| builder()->LoadAccumulatorWithRegister(Register::function_closure());
|
| - VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
|
| }
|
|
|
| void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
|
| @@ -3062,7 +3061,7 @@ void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
|
|
|
| // Store the new target we were called with in the given variable.
|
| builder()->LoadAccumulatorWithRegister(Register::new_target());
|
| - VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
|
| + BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());
|
|
|
| // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
|
| // and we need to make sure {BytecodeRegisterOptimizer} flushes its state
|
|
|