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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1431873006: Use a single Token::INIT for all variable initialization (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix arm, simplify fvar code Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/crankshaft/hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2); 1625 javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2);
1626 literal = NewNode(op, literal, proto); 1626 literal = NewNode(op, literal, proto);
1627 1627
1628 // Assign to class variable. 1628 // Assign to class variable.
1629 if (expr->class_variable_proxy() != nullptr) { 1629 if (expr->class_variable_proxy() != nullptr) {
1630 Variable* var = expr->class_variable_proxy()->var(); 1630 Variable* var = expr->class_variable_proxy()->var();
1631 FrameStateBeforeAndAfter states(this, BailoutId::None()); 1631 FrameStateBeforeAndAfter states(this, BailoutId::None());
1632 VectorSlotPair feedback = CreateVectorSlotPair( 1632 VectorSlotPair feedback = CreateVectorSlotPair(
1633 expr->NeedsProxySlot() ? expr->ProxySlot() 1633 expr->NeedsProxySlot() ? expr->ProxySlot()
1634 : FeedbackVectorSlot::Invalid()); 1634 : FeedbackVectorSlot::Invalid());
1635 BuildVariableAssignment(var, literal, Token::INIT_CONST, feedback, 1635 BuildVariableAssignment(var, literal, Token::INIT, feedback,
1636 BailoutId::None(), states); 1636 BailoutId::None(), states);
1637 } 1637 }
1638 ast_context()->ProduceValue(literal); 1638 ast_context()->ProduceValue(literal);
1639 } 1639 }
1640 1640
1641 1641
1642 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 1642 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
1643 UNREACHABLE(); 1643 UNREACHABLE();
1644 } 1644 }
1645 1645
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after
3195 3195
3196 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) { 3196 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) {
3197 if (this_function_var == nullptr) return nullptr; 3197 if (this_function_var == nullptr) return nullptr;
3198 3198
3199 // Retrieve the closure we were called with. 3199 // Retrieve the closure we were called with.
3200 Node* this_function = GetFunctionClosure(); 3200 Node* this_function = GetFunctionClosure();
3201 3201
3202 // Assign the object to the {.this_function} variable. This should never lazy 3202 // Assign the object to the {.this_function} variable. This should never lazy
3203 // deopt, so it is fine to send invalid bailout id. 3203 // deopt, so it is fine to send invalid bailout id.
3204 FrameStateBeforeAndAfter states(this, BailoutId::None()); 3204 FrameStateBeforeAndAfter states(this, BailoutId::None());
3205 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, 3205 BuildVariableAssignment(this_function_var, this_function, Token::INIT,
3206 VectorSlotPair(), BailoutId::None(), states); 3206 VectorSlotPair(), BailoutId::None(), states);
3207 return this_function; 3207 return this_function;
3208 } 3208 }
3209 3209
3210 3210
3211 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) { 3211 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) {
3212 if (new_target_var == nullptr) return nullptr; 3212 if (new_target_var == nullptr) return nullptr;
3213 3213
3214 // Retrieve the original constructor in case we are called as a constructor. 3214 // Retrieve the original constructor in case we are called as a constructor.
3215 const Operator* op = 3215 const Operator* op =
3216 javascript()->CallRuntime(Runtime::kGetOriginalConstructor, 0); 3216 javascript()->CallRuntime(Runtime::kGetOriginalConstructor, 0);
3217 Node* object = NewNode(op); 3217 Node* object = NewNode(op);
3218 PrepareFrameState(object, BailoutId::None()); 3218 PrepareFrameState(object, BailoutId::None());
3219 3219
3220 // Assign the object to the {new.target} variable. This should never lazy 3220 // Assign the object to the {new.target} variable. This should never lazy
3221 // deopt, so it is fine to send invalid bailout id. 3221 // deopt, so it is fine to send invalid bailout id.
3222 FrameStateBeforeAndAfter states(this, BailoutId::None()); 3222 FrameStateBeforeAndAfter states(this, BailoutId::None());
3223 BuildVariableAssignment(new_target_var, object, Token::INIT_CONST, 3223 BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(),
3224 VectorSlotPair(), BailoutId::None(), states); 3224 BailoutId::None(), states);
3225 return object; 3225 return object;
3226 } 3226 }
3227 3227
3228 3228
3229 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, 3229 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
3230 Node* not_hole) { 3230 Node* not_hole) {
3231 Node* the_hole = jsgraph()->TheHoleConstant(); 3231 Node* the_hole = jsgraph()->TheHoleConstant();
3232 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); 3232 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
3233 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, 3233 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check,
3234 for_hole, not_hole); 3234 for_hole, not_hole);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
3411 case VariableLocation::UNALLOCATED: { 3411 case VariableLocation::UNALLOCATED: {
3412 // Global var, const, or let variable. 3412 // Global var, const, or let variable.
3413 Handle<Name> name = variable->name(); 3413 Handle<Name> name = variable->name();
3414 Node* store = BuildGlobalStore(name, value, feedback); 3414 Node* store = BuildGlobalStore(name, value, feedback);
3415 states.AddToNode(store, bailout_id, combine); 3415 states.AddToNode(store, bailout_id, combine);
3416 return store; 3416 return store;
3417 } 3417 }
3418 case VariableLocation::PARAMETER: 3418 case VariableLocation::PARAMETER:
3419 case VariableLocation::LOCAL: 3419 case VariableLocation::LOCAL:
3420 // Local var, const, or let variable. 3420 // Local var, const, or let variable.
3421 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 3421 if (mode == CONST_LEGACY && op == Token::INIT) {
3422 // Perform an initialization check for legacy const variables. 3422 // Perform an initialization check for legacy const variables.
3423 Node* current = environment()->Lookup(variable); 3423 Node* current = environment()->Lookup(variable);
3424 if (current->op() != the_hole->op()) { 3424 if (current->op() != the_hole->op()) {
3425 value = BuildHoleCheckSilent(current, value, current); 3425 value = BuildHoleCheckSilent(current, value, current);
3426 } 3426 }
3427 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { 3427 } else if (mode == CONST_LEGACY && op != Token::INIT) {
3428 // Non-initializing assignment to legacy const is 3428 // Non-initializing assignment to legacy const is
3429 // - exception in strict mode. 3429 // - exception in strict mode.
3430 // - ignored in sloppy mode. 3430 // - ignored in sloppy mode.
3431 if (is_strict(language_mode())) { 3431 if (is_strict(language_mode())) {
3432 return BuildThrowConstAssignError(bailout_id); 3432 return BuildThrowConstAssignError(bailout_id);
3433 } 3433 }
3434 return value; 3434 return value;
3435 } else if (mode == LET && op == Token::INIT_LET) { 3435 } else if (mode == LET && op == Token::INIT) {
3436 // No initialization check needed because scoping guarantees it. Note 3436 // No initialization check needed because scoping guarantees it. Note
3437 // that we still perform a lookup to keep the variable live, because 3437 // that we still perform a lookup to keep the variable live, because
3438 // baseline code might contain debug code that inspects the variable. 3438 // baseline code might contain debug code that inspects the variable.
3439 Node* current = environment()->Lookup(variable); 3439 Node* current = environment()->Lookup(variable);
3440 CHECK_NOT_NULL(current); 3440 CHECK_NOT_NULL(current);
3441 } else if (mode == LET && op != Token::INIT_LET) { 3441 } else if (mode == LET && op != Token::INIT) {
3442 // Perform an initialization check for let declared variables. 3442 // Perform an initialization check for let declared variables.
3443 Node* current = environment()->Lookup(variable); 3443 Node* current = environment()->Lookup(variable);
3444 if (current->op() == the_hole->op()) { 3444 if (current->op() == the_hole->op()) {
3445 return BuildThrowReferenceError(variable, bailout_id); 3445 return BuildThrowReferenceError(variable, bailout_id);
3446 } else if (current->opcode() == IrOpcode::kPhi) { 3446 } else if (current->opcode() == IrOpcode::kPhi) {
3447 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3447 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3448 } 3448 }
3449 } else if (mode == CONST && op == Token::INIT_CONST) { 3449 } else if (mode == CONST && op == Token::INIT) {
3450 // Perform an initialization check for const {this} variables. 3450 // Perform an initialization check for const {this} variables.
3451 // Note that the {this} variable is the only const variable being able 3451 // Note that the {this} variable is the only const variable being able
3452 // to trigger bind operations outside the TDZ, via {super} calls. 3452 // to trigger bind operations outside the TDZ, via {super} calls.
3453 Node* current = environment()->Lookup(variable); 3453 Node* current = environment()->Lookup(variable);
3454 if (current->op() != the_hole->op() && variable->is_this()) { 3454 if (current->op() != the_hole->op() && variable->is_this()) {
3455 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); 3455 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
3456 } 3456 }
3457 } else if (mode == CONST && op != Token::INIT_CONST) { 3457 } else if (mode == CONST && op != Token::INIT) {
3458 // Assignment to const is exception in all modes. 3458 // Assignment to const is exception in all modes.
3459 Node* current = environment()->Lookup(variable); 3459 Node* current = environment()->Lookup(variable);
3460 if (current->op() == the_hole->op()) { 3460 if (current->op() == the_hole->op()) {
3461 return BuildThrowReferenceError(variable, bailout_id); 3461 return BuildThrowReferenceError(variable, bailout_id);
3462 } else if (current->opcode() == IrOpcode::kPhi) { 3462 } else if (current->opcode() == IrOpcode::kPhi) {
3463 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3463 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3464 } 3464 }
3465 return BuildThrowConstAssignError(bailout_id); 3465 return BuildThrowConstAssignError(bailout_id);
3466 } 3466 }
3467 environment()->Bind(variable, value); 3467 environment()->Bind(variable, value);
3468 return value; 3468 return value;
3469 case VariableLocation::CONTEXT: { 3469 case VariableLocation::CONTEXT: {
3470 // Context variable (potentially up the context chain). 3470 // Context variable (potentially up the context chain).
3471 int depth = current_scope()->ContextChainLength(variable->scope()); 3471 int depth = current_scope()->ContextChainLength(variable->scope());
3472 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 3472 if (mode == CONST_LEGACY && op == Token::INIT) {
3473 // Perform an initialization check for legacy const variables. 3473 // Perform an initialization check for legacy const variables.
3474 const Operator* op = 3474 const Operator* op =
3475 javascript()->LoadContext(depth, variable->index(), false); 3475 javascript()->LoadContext(depth, variable->index(), false);
3476 Node* current = NewNode(op, current_context()); 3476 Node* current = NewNode(op, current_context());
3477 value = BuildHoleCheckSilent(current, value, current); 3477 value = BuildHoleCheckSilent(current, value, current);
3478 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { 3478 } else if (mode == CONST_LEGACY && op != Token::INIT) {
3479 // Non-initializing assignment to legacy const is 3479 // Non-initializing assignment to legacy const is
3480 // - exception in strict mode. 3480 // - exception in strict mode.
3481 // - ignored in sloppy mode. 3481 // - ignored in sloppy mode.
3482 if (is_strict(language_mode())) { 3482 if (is_strict(language_mode())) {
3483 return BuildThrowConstAssignError(bailout_id); 3483 return BuildThrowConstAssignError(bailout_id);
3484 } 3484 }
3485 return value; 3485 return value;
3486 } else if (mode == LET && op != Token::INIT_LET) { 3486 } else if (mode == LET && op != Token::INIT) {
3487 // Perform an initialization check for let declared variables. 3487 // Perform an initialization check for let declared variables.
3488 const Operator* op = 3488 const Operator* op =
3489 javascript()->LoadContext(depth, variable->index(), false); 3489 javascript()->LoadContext(depth, variable->index(), false);
3490 Node* current = NewNode(op, current_context()); 3490 Node* current = NewNode(op, current_context());
3491 value = BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3491 value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3492 } else if (mode == CONST && op == Token::INIT_CONST) { 3492 } else if (mode == CONST && op == Token::INIT) {
3493 // Perform an initialization check for const {this} variables. 3493 // Perform an initialization check for const {this} variables.
3494 // Note that the {this} variable is the only const variable being able 3494 // Note that the {this} variable is the only const variable being able
3495 // to trigger bind operations outside the TDZ, via {super} calls. 3495 // to trigger bind operations outside the TDZ, via {super} calls.
3496 if (variable->is_this()) { 3496 if (variable->is_this()) {
3497 const Operator* op = 3497 const Operator* op =
3498 javascript()->LoadContext(depth, variable->index(), false); 3498 javascript()->LoadContext(depth, variable->index(), false);
3499 Node* current = NewNode(op, current_context()); 3499 Node* current = NewNode(op, current_context());
3500 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); 3500 value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
3501 } 3501 }
3502 } else if (mode == CONST && op != Token::INIT_CONST) { 3502 } else if (mode == CONST && op != Token::INIT) {
3503 // Assignment to const is exception in all modes. 3503 // Assignment to const is exception in all modes.
3504 const Operator* op = 3504 const Operator* op =
3505 javascript()->LoadContext(depth, variable->index(), false); 3505 javascript()->LoadContext(depth, variable->index(), false);
3506 Node* current = NewNode(op, current_context()); 3506 Node* current = NewNode(op, current_context());
3507 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3507 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3508 return BuildThrowConstAssignError(bailout_id); 3508 return BuildThrowConstAssignError(bailout_id);
3509 } 3509 }
3510 const Operator* op = javascript()->StoreContext(depth, variable->index()); 3510 const Operator* op = javascript()->StoreContext(depth, variable->index());
3511 return NewNode(op, current_context(), value); 3511 return NewNode(op, current_context(), value);
3512 } 3512 }
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
4296 // Phi does not exist yet, introduce one. 4296 // Phi does not exist yet, introduce one.
4297 value = NewPhi(inputs, value, control); 4297 value = NewPhi(inputs, value, control);
4298 value->ReplaceInput(inputs - 1, other); 4298 value->ReplaceInput(inputs - 1, other);
4299 } 4299 }
4300 return value; 4300 return value;
4301 } 4301 }
4302 4302
4303 } // namespace compiler 4303 } // namespace compiler
4304 } // namespace internal 4304 } // namespace internal
4305 } // namespace v8 4305 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/crankshaft/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698