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

Side by Side Diff: src/ast/scopes.cc

Issue 2411873004: [ignition] Eliminate hole checks where statically possible for loads and stores (Closed)
Patch Set: Move logic to scope analysis time 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/ast/ast.h" 10 #include "src/ast/ast.h"
(...skipping 1593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 // We don't know what the (potentially lazy parsed) inner function 1604 // We don't know what the (potentially lazy parsed) inner function
1605 // does with the variable; pessimistically assume that it's assigned. 1605 // does with the variable; pessimistically assume that it's assigned.
1606 var->set_maybe_assigned(); 1606 var->set_maybe_assigned();
1607 } 1607 }
1608 } 1608 }
1609 scope = scope->outer_scope_; 1609 scope = scope->outer_scope_;
1610 } 1610 }
1611 } 1611 }
1612 } 1612 }
1613 1613
1614 namespace {
1615
1616 bool AccessNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
1617 if (!var->binding_needs_init()) {
1618 return false;
1619 }
1620
1621 DCHECK(var->scope() != NULL);
1622
1623 if (var->is_this()) {
1624 DCHECK(
1625 IsSubclassConstructor(scope->GetDeclarationScope()->function_kind()));
1626 // TODO(littledan): implement 'this' hole check elimination.
1627 return true;
1628 }
1629
1630 // We should always have valid source positions.
1631 DCHECK(var->initializer_position() != kNoSourcePosition);
1632 DCHECK(proxy->position() != kNoSourcePosition);
1633
1634 // Check if the binding really needs an initialization check. The check
1635 // can be skipped in the following situation: we have a LET or CONST
1636 // binding, both the Variable and the VariableProxy have the same
1637 // declaration scope (i.e. they are both in global code, in the
1638 // same function or in the same eval code), the VariableProxy is in
1639 // the source physically located after the initializer of the variable,
1640 // and that the initializer cannot be skipped due to a nonlinear scope.
1641 //
1642 // The condition on the declaration scopes is a conservative check for
1643 // nested functions that access a binding and are called before the
1644 // binding is initialized:
1645 // function() { f(); let x = 1; function f() { x = 2; } }
1646 //
1647 // The check cannot be skipped on non-linear scopes, namely switch
1648 // scopes, to ensure tests are done in cases like the following:
1649 // switch (1) { case 0: let x = 2; case 1: f(x); }
1650 // The scope of the variable needs to be checked, in case the use is
1651 // in a sub-block which may be linear.
1652 return var->scope()->GetDeclarationScope() != scope->GetDeclarationScope() ||
1653 var->scope()->is_nonlinear() ||
1654 var->initializer_position() >= proxy->position();
1655 }
1656
1657 } // anonymous namespace
1658
1614 void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) { 1659 void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
1615 #ifdef DEBUG 1660 #ifdef DEBUG
1616 if (info->script_is_native()) { 1661 if (info->script_is_native()) {
1617 // To avoid polluting the global object in native scripts 1662 // To avoid polluting the global object in native scripts
1618 // - Variables must not be allocated to the global scope. 1663 // - Variables must not be allocated to the global scope.
1619 CHECK_NOT_NULL(outer_scope()); 1664 CHECK_NOT_NULL(outer_scope());
1620 // - Variables must be bound locally or unallocated. 1665 // - Variables must be bound locally or unallocated.
1621 if (var->IsGlobalObjectProperty()) { 1666 if (var->IsGlobalObjectProperty()) {
1622 // The following variable name may be minified. If so, disable 1667 // The following variable name may be minified. If so, disable
1623 // minification in js2c.py for better output. 1668 // minification in js2c.py for better output.
1624 Handle<String> name = proxy->raw_name()->string(); 1669 Handle<String> name = proxy->raw_name()->string();
1625 V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.", 1670 V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.",
1626 name->ToCString().get()); 1671 name->ToCString().get());
1627 } 1672 }
1628 VariableLocation location = var->location(); 1673 VariableLocation location = var->location();
1629 CHECK(location == VariableLocation::LOCAL || 1674 CHECK(location == VariableLocation::LOCAL ||
1630 location == VariableLocation::CONTEXT || 1675 location == VariableLocation::CONTEXT ||
1631 location == VariableLocation::PARAMETER || 1676 location == VariableLocation::PARAMETER ||
1632 location == VariableLocation::UNALLOCATED); 1677 location == VariableLocation::UNALLOCATED);
1633 } 1678 }
1634 #endif 1679 #endif
1635 1680
1636 DCHECK_NOT_NULL(var); 1681 DCHECK_NOT_NULL(var);
1637 if (proxy->is_assigned()) var->set_maybe_assigned(); 1682 if (proxy->is_assigned()) var->set_maybe_assigned();
1683 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check();
1638 proxy->BindTo(var); 1684 proxy->BindTo(var);
1639 } 1685 }
1640 1686
1641 void Scope::ResolveVariablesRecursively(ParseInfo* info) { 1687 void Scope::ResolveVariablesRecursively(ParseInfo* info) {
1642 DCHECK(info->script_scope()->is_script_scope()); 1688 DCHECK(info->script_scope()->is_script_scope());
1643 1689
1644 // Resolve unresolved variables for this scope. 1690 // Resolve unresolved variables for this scope.
1645 for (VariableProxy* proxy = unresolved_; proxy != nullptr; 1691 for (VariableProxy* proxy = unresolved_; proxy != nullptr;
1646 proxy = proxy->next_unresolved()) { 1692 proxy = proxy->next_unresolved()) {
1647 ResolveVariable(info, proxy); 1693 ResolveVariable(info, proxy);
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 Variable* function = 1991 Variable* function =
1946 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; 1992 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
1947 bool is_function_var_in_context = 1993 bool is_function_var_in_context =
1948 function != nullptr && function->IsContextSlot(); 1994 function != nullptr && function->IsContextSlot();
1949 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1995 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1950 (is_function_var_in_context ? 1 : 0); 1996 (is_function_var_in_context ? 1 : 0);
1951 } 1997 }
1952 1998
1953 } // namespace internal 1999 } // namespace internal
1954 } // namespace v8 2000 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698