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

Side by Side 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, 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 | « src/interpreter/bytecode-generator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-info.h" 10 #include "src/compilation-info.h"
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 builder() 823 builder()
824 ->LoadLiteral(variable->name()) 824 ->LoadLiteral(variable->name())
825 .StoreAccumulatorInRegister(name) 825 .StoreAccumulatorInRegister(name)
826 .CallRuntime(Runtime::kDeclareEvalVar, name); 826 .CallRuntime(Runtime::kDeclareEvalVar, name);
827 break; 827 break;
828 } 828 }
829 case VariableLocation::MODULE: 829 case VariableLocation::MODULE:
830 if (variable->IsExport() && variable->binding_needs_init()) { 830 if (variable->IsExport() && variable->binding_needs_init()) {
831 builder()->LoadTheHole(); 831 builder()->LoadTheHole();
832 BuildVariableAssignment(variable, Token::INIT, 832 BuildVariableAssignment(variable, Token::INIT,
833 FeedbackVectorSlot::Invalid(), false); 833 FeedbackVectorSlot::Invalid(),
834 HoleCheckMode::kElided);
834 } 835 }
835 // Nothing to do for imports. 836 // Nothing to do for imports.
836 break; 837 break;
837 } 838 }
838 } 839 }
839 840
840 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 841 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
841 Variable* variable = decl->proxy()->var(); 842 Variable* variable = decl->proxy()->var();
842 DCHECK(variable->mode() == LET || variable->mode() == VAR); 843 DCHECK(variable->mode() == LET || variable->mode() == VAR);
843 switch (variable->location()) { 844 switch (variable->location()) {
844 case VariableLocation::UNALLOCATED: { 845 case VariableLocation::UNALLOCATED: {
845 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); 846 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
846 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); 847 globals_builder()->AddFunctionDeclaration(slot, decl->fun());
847 break; 848 break;
848 } 849 }
849 case VariableLocation::PARAMETER: 850 case VariableLocation::PARAMETER:
850 case VariableLocation::LOCAL: { 851 case VariableLocation::LOCAL: {
851 VisitForAccumulatorValue(decl->fun()); 852 VisitForAccumulatorValue(decl->fun());
852 BuildVariableAssignment(variable, Token::INIT, 853 BuildVariableAssignment(variable, Token::INIT,
853 FeedbackVectorSlot::Invalid(), false); 854 FeedbackVectorSlot::Invalid(),
855 HoleCheckMode::kElided);
854 break; 856 break;
855 } 857 }
856 case VariableLocation::CONTEXT: { 858 case VariableLocation::CONTEXT: {
857 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); 859 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
858 VisitForAccumulatorValue(decl->fun()); 860 VisitForAccumulatorValue(decl->fun());
859 builder()->StoreContextSlot(execution_context()->reg(), variable->index(), 861 builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
860 0); 862 0);
861 break; 863 break;
862 } 864 }
863 case VariableLocation::LOOKUP: { 865 case VariableLocation::LOOKUP: {
864 RegisterList args = register_allocator()->NewRegisterList(2); 866 RegisterList args = register_allocator()->NewRegisterList(2);
865 builder() 867 builder()
866 ->LoadLiteral(variable->name()) 868 ->LoadLiteral(variable->name())
867 .StoreAccumulatorInRegister(args[0]); 869 .StoreAccumulatorInRegister(args[0]);
868 VisitForAccumulatorValue(decl->fun()); 870 VisitForAccumulatorValue(decl->fun());
869 builder()->StoreAccumulatorInRegister(args[1]).CallRuntime( 871 builder()->StoreAccumulatorInRegister(args[1]).CallRuntime(
870 Runtime::kDeclareEvalFunction, args); 872 Runtime::kDeclareEvalFunction, args);
871 break; 873 break;
872 } 874 }
873 case VariableLocation::MODULE: 875 case VariableLocation::MODULE:
874 DCHECK_EQ(variable->mode(), LET); 876 DCHECK_EQ(variable->mode(), LET);
875 DCHECK(variable->IsExport()); 877 DCHECK(variable->IsExport());
876 VisitForAccumulatorValue(decl->fun()); 878 VisitForAccumulatorValue(decl->fun());
877 BuildVariableAssignment(variable, Token::INIT, 879 BuildVariableAssignment(variable, Token::INIT,
878 FeedbackVectorSlot::Invalid(), false); 880 FeedbackVectorSlot::Invalid(),
881 HoleCheckMode::kElided);
879 break; 882 break;
880 } 883 }
881 } 884 }
882 885
883 void BytecodeGenerator::VisitModuleNamespaceImports() { 886 void BytecodeGenerator::VisitModuleNamespaceImports() {
884 if (!scope()->is_module_scope()) return; 887 if (!scope()->is_module_scope()) return;
885 888
886 RegisterAllocationScope register_scope(this); 889 RegisterAllocationScope register_scope(this);
887 Register module_request = register_allocator()->NewRegister(); 890 Register module_request = register_allocator()->NewRegister();
888 891
889 ModuleDescriptor* descriptor = scope()->AsModuleScope()->module(); 892 ModuleDescriptor* descriptor = scope()->AsModuleScope()->module();
890 for (auto entry : descriptor->namespace_imports()) { 893 for (auto entry : descriptor->namespace_imports()) {
891 builder() 894 builder()
892 ->LoadLiteral(Smi::FromInt(entry->module_request)) 895 ->LoadLiteral(Smi::FromInt(entry->module_request))
893 .StoreAccumulatorInRegister(module_request) 896 .StoreAccumulatorInRegister(module_request)
894 .CallRuntime(Runtime::kGetModuleNamespace, module_request); 897 .CallRuntime(Runtime::kGetModuleNamespace, module_request);
895 Variable* var = scope()->LookupLocal(entry->local_name); 898 Variable* var = scope()->LookupLocal(entry->local_name);
896 DCHECK_NOT_NULL(var); 899 DCHECK_NOT_NULL(var);
897 BuildVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid(), 900 BuildVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid(),
898 false); 901 HoleCheckMode::kElided);
899 } 902 }
900 } 903 }
901 904
902 void BytecodeGenerator::VisitDeclarations( 905 void BytecodeGenerator::VisitDeclarations(
903 ZoneList<Declaration*>* declarations) { 906 ZoneList<Declaration*>* declarations) {
904 RegisterAllocationScope register_scope(this); 907 RegisterAllocationScope register_scope(this);
905 DCHECK(globals_builder()->empty()); 908 DCHECK(globals_builder()->empty());
906 for (int i = 0; i < declarations->length(); i++) { 909 for (int i = 0; i < declarations->length(); i++) {
907 RegisterAllocationScope register_scope(this); 910 RegisterAllocationScope register_scope(this);
908 Visit(declarations->at(i)); 911 Visit(declarations->at(i));
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 DCHECK(expr->IsValidReferenceExpression()); 1146 DCHECK(expr->IsValidReferenceExpression());
1144 1147
1145 // Evaluate assignment starting with the value to be stored in the 1148 // Evaluate assignment starting with the value to be stored in the
1146 // accumulator. 1149 // accumulator.
1147 Property* property = expr->AsProperty(); 1150 Property* property = expr->AsProperty();
1148 LhsKind assign_type = Property::GetAssignType(property); 1151 LhsKind assign_type = Property::GetAssignType(property);
1149 switch (assign_type) { 1152 switch (assign_type) {
1150 case VARIABLE: { 1153 case VARIABLE: {
1151 VariableProxy* proxy = expr->AsVariableProxy(); 1154 VariableProxy* proxy = expr->AsVariableProxy();
1152 BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot, 1155 BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot,
1153 proxy->needs_hole_check()); 1156 proxy->hole_check_mode());
1154 break; 1157 break;
1155 } 1158 }
1156 case NAMED_PROPERTY: { 1159 case NAMED_PROPERTY: {
1157 RegisterAllocationScope register_scope(this); 1160 RegisterAllocationScope register_scope(this);
1158 Register value = register_allocator()->NewRegister(); 1161 Register value = register_allocator()->NewRegister();
1159 builder()->StoreAccumulatorInRegister(value); 1162 builder()->StoreAccumulatorInRegister(value);
1160 Register object = VisitForRegisterValue(property->obj()); 1163 Register object = VisitForRegisterValue(property->obj());
1161 Handle<String> name = property->key()->AsLiteral()->AsPropertyName(); 1164 Handle<String> name = property->key()->AsLiteral()->AsPropertyName();
1162 builder()->LoadAccumulatorWithRegister(value); 1165 builder()->LoadAccumulatorWithRegister(value);
1163 builder()->StoreNamedProperty(object, name, feedback_index(slot), 1166 builder()->StoreNamedProperty(object, name, feedback_index(slot),
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 .StoreAccumulatorInRegister(prototype); 1397 .StoreAccumulatorInRegister(prototype);
1395 1398
1396 VisitClassLiteralProperties(expr, literal, prototype); 1399 VisitClassLiteralProperties(expr, literal, prototype);
1397 builder()->CallRuntime(Runtime::kToFastProperties, literal); 1400 builder()->CallRuntime(Runtime::kToFastProperties, literal);
1398 // Assign to class variable. 1401 // Assign to class variable.
1399 if (expr->class_variable_proxy() != nullptr) { 1402 if (expr->class_variable_proxy() != nullptr) {
1400 VariableProxy* proxy = expr->class_variable_proxy(); 1403 VariableProxy* proxy = expr->class_variable_proxy();
1401 FeedbackVectorSlot slot = expr->NeedsProxySlot() 1404 FeedbackVectorSlot slot = expr->NeedsProxySlot()
1402 ? expr->ProxySlot() 1405 ? expr->ProxySlot()
1403 : FeedbackVectorSlot::Invalid(); 1406 : FeedbackVectorSlot::Invalid();
1404 BuildVariableAssignment(proxy->var(), Token::INIT, slot, false); 1407 BuildVariableAssignment(proxy->var(), Token::INIT, slot,
1408 HoleCheckMode::kElided);
1405 } 1409 }
1406 } 1410 }
1407 1411
1408 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition( 1412 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition(
1409 ClassLiteral* expr) { 1413 ClassLiteral* expr) {
1410 RegisterAllocationScope register_scope(this); 1414 RegisterAllocationScope register_scope(this);
1411 RegisterList args = register_allocator()->NewRegisterList(4); 1415 RegisterList args = register_allocator()->NewRegisterList(4);
1412 VisitForAccumulatorValueOrTheHole(expr->extends()); 1416 VisitForAccumulatorValueOrTheHole(expr->extends());
1413 builder()->StoreAccumulatorInRegister(args[0]); 1417 builder()->StoreAccumulatorInRegister(args[0]);
1414 VisitForRegisterValue(expr->constructor(), args[1]); 1418 VisitForRegisterValue(expr->constructor(), args[1]);
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 1773
1770 if (!literal_in_accumulator) { 1774 if (!literal_in_accumulator) {
1771 // Restore literal array into accumulator. 1775 // Restore literal array into accumulator.
1772 builder()->LoadAccumulatorWithRegister(literal); 1776 builder()->LoadAccumulatorWithRegister(literal);
1773 } 1777 }
1774 } 1778 }
1775 1779
1776 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 1780 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
1777 builder()->SetExpressionPosition(proxy); 1781 builder()->SetExpressionPosition(proxy);
1778 BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(), 1782 BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
1779 proxy->needs_hole_check()); 1783 proxy->hole_check_mode());
1780 } 1784 }
1781 1785
1782 void BytecodeGenerator::BuildVariableLoad(Variable* variable, 1786 void BytecodeGenerator::BuildVariableLoad(Variable* variable,
1783 FeedbackVectorSlot slot, 1787 FeedbackVectorSlot slot,
1784 bool needs_hole_check, 1788 HoleCheckMode hole_check_mode,
1785 TypeofMode typeof_mode) { 1789 TypeofMode typeof_mode) {
1786 switch (variable->location()) { 1790 switch (variable->location()) {
1787 case VariableLocation::LOCAL: { 1791 case VariableLocation::LOCAL: {
1788 Register source(Register(variable->index())); 1792 Register source(Register(variable->index()));
1789 // We need to load the variable into the accumulator, even when in a 1793 // We need to load the variable into the accumulator, even when in a
1790 // VisitForRegisterScope, in order to avoid register aliasing if 1794 // VisitForRegisterScope, in order to avoid register aliasing if
1791 // subsequent expressions assign to the same variable. 1795 // subsequent expressions assign to the same variable.
1792 builder()->LoadAccumulatorWithRegister(source); 1796 builder()->LoadAccumulatorWithRegister(source);
1793 if (needs_hole_check) BuildThrowIfHole(variable->name()); 1797 if (hole_check_mode == HoleCheckMode::kRequired) {
1798 BuildThrowIfHole(variable->name());
1799 }
1794 break; 1800 break;
1795 } 1801 }
1796 case VariableLocation::PARAMETER: { 1802 case VariableLocation::PARAMETER: {
1797 // The parameter indices are shifted by 1 (receiver is variable 1803 // The parameter indices are shifted by 1 (receiver is variable
1798 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 1804 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
1799 Register source = builder()->Parameter(variable->index() + 1); 1805 Register source = builder()->Parameter(variable->index() + 1);
1800 // We need to load the variable into the accumulator, even when in a 1806 // We need to load the variable into the accumulator, even when in a
1801 // VisitForRegisterScope, in order to avoid register aliasing if 1807 // VisitForRegisterScope, in order to avoid register aliasing if
1802 // subsequent expressions assign to the same variable. 1808 // subsequent expressions assign to the same variable.
1803 builder()->LoadAccumulatorWithRegister(source); 1809 builder()->LoadAccumulatorWithRegister(source);
1804 if (needs_hole_check) BuildThrowIfHole(variable->name()); 1810 if (hole_check_mode == HoleCheckMode::kRequired) {
1811 BuildThrowIfHole(variable->name());
1812 }
1805 break; 1813 break;
1806 } 1814 }
1807 case VariableLocation::UNALLOCATED: { 1815 case VariableLocation::UNALLOCATED: {
1808 builder()->LoadGlobal(feedback_index(slot), typeof_mode); 1816 builder()->LoadGlobal(feedback_index(slot), typeof_mode);
1809 break; 1817 break;
1810 } 1818 }
1811 case VariableLocation::CONTEXT: { 1819 case VariableLocation::CONTEXT: {
1812 int depth = execution_context()->ContextChainDepth(variable->scope()); 1820 int depth = execution_context()->ContextChainDepth(variable->scope());
1813 ContextScope* context = execution_context()->Previous(depth); 1821 ContextScope* context = execution_context()->Previous(depth);
1814 Register context_reg; 1822 Register context_reg;
1815 if (context) { 1823 if (context) {
1816 context_reg = context->reg(); 1824 context_reg = context->reg();
1817 depth = 0; 1825 depth = 0;
1818 } else { 1826 } else {
1819 context_reg = execution_context()->reg(); 1827 context_reg = execution_context()->reg();
1820 } 1828 }
1821 1829
1822 builder()->LoadContextSlot(context_reg, variable->index(), depth); 1830 builder()->LoadContextSlot(context_reg, variable->index(), depth);
1823 if (needs_hole_check) BuildThrowIfHole(variable->name()); 1831 if (hole_check_mode == HoleCheckMode::kRequired) {
1832 BuildThrowIfHole(variable->name());
1833 }
1824 break; 1834 break;
1825 } 1835 }
1826 case VariableLocation::LOOKUP: { 1836 case VariableLocation::LOOKUP: {
1827 switch (variable->mode()) { 1837 switch (variable->mode()) {
1828 case DYNAMIC_LOCAL: { 1838 case DYNAMIC_LOCAL: {
1829 Variable* local_variable = variable->local_if_not_shadowed(); 1839 Variable* local_variable = variable->local_if_not_shadowed();
1830 int depth = 1840 int depth =
1831 execution_context()->ContextChainDepth(local_variable->scope()); 1841 execution_context()->ContextChainDepth(local_variable->scope());
1832 builder()->LoadLookupContextSlot(variable->name(), typeof_mode, 1842 builder()->LoadLookupContextSlot(variable->name(), typeof_mode,
1833 local_variable->index(), depth); 1843 local_variable->index(), depth);
1834 if (needs_hole_check) BuildThrowIfHole(variable->name()); 1844 if (hole_check_mode == HoleCheckMode::kRequired) {
1845 BuildThrowIfHole(variable->name());
1846 }
1835 break; 1847 break;
1836 } 1848 }
1837 case DYNAMIC_GLOBAL: { 1849 case DYNAMIC_GLOBAL: {
1838 int depth = scope()->ContextChainLengthUntilOutermostSloppyEval(); 1850 int depth = scope()->ContextChainLengthUntilOutermostSloppyEval();
1839 builder()->LoadLookupGlobalSlot(variable->name(), typeof_mode, 1851 builder()->LoadLookupGlobalSlot(variable->name(), typeof_mode,
1840 feedback_index(slot), depth); 1852 feedback_index(slot), depth);
1841 break; 1853 break;
1842 } 1854 }
1843 default: 1855 default:
1844 builder()->LoadLookupSlot(variable->name(), typeof_mode); 1856 builder()->LoadLookupSlot(variable->name(), typeof_mode);
(...skipping 14 matching lines...) Expand all
1859 auto it = descriptor->regular_imports().find(variable->raw_name()); 1871 auto it = descriptor->regular_imports().find(variable->raw_name());
1860 DCHECK(it != descriptor->regular_imports().end()); 1872 DCHECK(it != descriptor->regular_imports().end());
1861 RegisterList args = register_allocator()->NewRegisterList(2); 1873 RegisterList args = register_allocator()->NewRegisterList(2);
1862 builder() 1874 builder()
1863 ->LoadLiteral(it->second->import_name->string()) 1875 ->LoadLiteral(it->second->import_name->string())
1864 .StoreAccumulatorInRegister(args[0]) 1876 .StoreAccumulatorInRegister(args[0])
1865 .LoadLiteral(Smi::FromInt(it->second->module_request)) 1877 .LoadLiteral(Smi::FromInt(it->second->module_request))
1866 .StoreAccumulatorInRegister(args[1]) 1878 .StoreAccumulatorInRegister(args[1])
1867 .CallRuntime(Runtime::kLoadModuleImport, args); 1879 .CallRuntime(Runtime::kLoadModuleImport, args);
1868 } 1880 }
1869 if (needs_hole_check) BuildThrowIfHole(variable->name()); 1881 if (hole_check_mode == HoleCheckMode::kRequired) {
1882 BuildThrowIfHole(variable->name());
1883 }
1870 break; 1884 break;
1871 } 1885 }
1872 } 1886 }
1873 } 1887 }
1874 1888
1875 void BytecodeGenerator::BuildVariableLoadForAccumulatorValue( 1889 void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
1876 Variable* variable, FeedbackVectorSlot slot, bool needs_hole_check, 1890 Variable* variable, FeedbackVectorSlot slot, HoleCheckMode hole_check_mode,
1877 TypeofMode typeof_mode) { 1891 TypeofMode typeof_mode) {
1878 ValueResultScope accumulator_result(this); 1892 ValueResultScope accumulator_result(this);
1879 BuildVariableLoad(variable, slot, needs_hole_check, typeof_mode); 1893 BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode);
1880 } 1894 }
1881 1895
1882 void BytecodeGenerator::BuildReturn() { 1896 void BytecodeGenerator::BuildReturn() {
1883 if (FLAG_trace) { 1897 if (FLAG_trace) {
1884 RegisterAllocationScope register_scope(this); 1898 RegisterAllocationScope register_scope(this);
1885 Register result = register_allocator()->NewRegister(); 1899 Register result = register_allocator()->NewRegister();
1886 // Runtime returns {result} value, preserving accumulator. 1900 // Runtime returns {result} value, preserving accumulator.
1887 builder()->StoreAccumulatorInRegister(result).CallRuntime( 1901 builder()->StoreAccumulatorInRegister(result).CallRuntime(
1888 Runtime::kTraceExit, result); 1902 Runtime::kTraceExit, result);
1889 } 1903 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 // Perform an initialization check for 'this'. 'this' variable is the 1955 // Perform an initialization check for 'this'. 'this' variable is the
1942 // only variable able to trigger bind operations outside the TDZ 1956 // only variable able to trigger bind operations outside the TDZ
1943 // via 'super' calls. 1957 // via 'super' calls.
1944 BuildThrowIfNotHole(variable->name()); 1958 BuildThrowIfNotHole(variable->name());
1945 } 1959 }
1946 } 1960 }
1947 1961
1948 void BytecodeGenerator::BuildVariableAssignment(Variable* variable, 1962 void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
1949 Token::Value op, 1963 Token::Value op,
1950 FeedbackVectorSlot slot, 1964 FeedbackVectorSlot slot,
1951 bool needs_hole_check) { 1965 HoleCheckMode hole_check_mode) {
1952 VariableMode mode = variable->mode(); 1966 VariableMode mode = variable->mode();
1953 RegisterAllocationScope assignment_register_scope(this); 1967 RegisterAllocationScope assignment_register_scope(this);
1954 BytecodeLabel end_label; 1968 BytecodeLabel end_label;
1955 switch (variable->location()) { 1969 switch (variable->location()) {
1956 case VariableLocation::PARAMETER: 1970 case VariableLocation::PARAMETER:
1957 case VariableLocation::LOCAL: { 1971 case VariableLocation::LOCAL: {
1958 Register destination; 1972 Register destination;
1959 if (VariableLocation::PARAMETER == variable->location()) { 1973 if (VariableLocation::PARAMETER == variable->location()) {
1960 destination = Register(builder()->Parameter(variable->index() + 1)); 1974 destination = Register(builder()->Parameter(variable->index() + 1));
1961 } else { 1975 } else {
1962 destination = Register(variable->index()); 1976 destination = Register(variable->index());
1963 } 1977 }
1964 1978
1965 if (needs_hole_check) { 1979 if (hole_check_mode == HoleCheckMode::kRequired) {
1966 // Load destination to check for hole. 1980 // Load destination to check for hole.
1967 Register value_temp = register_allocator()->NewRegister(); 1981 Register value_temp = register_allocator()->NewRegister();
1968 builder() 1982 builder()
1969 ->StoreAccumulatorInRegister(value_temp) 1983 ->StoreAccumulatorInRegister(value_temp)
1970 .LoadAccumulatorWithRegister(destination); 1984 .LoadAccumulatorWithRegister(destination);
1971 1985
1972 BuildHoleCheckForVariableAssignment(variable, op); 1986 BuildHoleCheckForVariableAssignment(variable, op);
1973 builder()->LoadAccumulatorWithRegister(value_temp); 1987 builder()->LoadAccumulatorWithRegister(value_temp);
1974 } 1988 }
1975 1989
(...skipping 14 matching lines...) Expand all
1990 ContextScope* context = execution_context()->Previous(depth); 2004 ContextScope* context = execution_context()->Previous(depth);
1991 Register context_reg; 2005 Register context_reg;
1992 2006
1993 if (context) { 2007 if (context) {
1994 context_reg = context->reg(); 2008 context_reg = context->reg();
1995 depth = 0; 2009 depth = 0;
1996 } else { 2010 } else {
1997 context_reg = execution_context()->reg(); 2011 context_reg = execution_context()->reg();
1998 } 2012 }
1999 2013
2000 if (needs_hole_check) { 2014 if (hole_check_mode == HoleCheckMode::kRequired) {
2001 // Load destination to check for hole. 2015 // Load destination to check for hole.
2002 Register value_temp = register_allocator()->NewRegister(); 2016 Register value_temp = register_allocator()->NewRegister();
2003 builder() 2017 builder()
2004 ->StoreAccumulatorInRegister(value_temp) 2018 ->StoreAccumulatorInRegister(value_temp)
2005 .LoadContextSlot(context_reg, variable->index(), depth); 2019 .LoadContextSlot(context_reg, variable->index(), depth);
2006 2020
2007 BuildHoleCheckForVariableAssignment(variable, op); 2021 BuildHoleCheckForVariableAssignment(variable, op);
2008 builder()->LoadAccumulatorWithRegister(value_temp); 2022 builder()->LoadAccumulatorWithRegister(value_temp);
2009 } 2023 }
2010 2024
(...skipping 25 matching lines...) Expand all
2036 // There may be several export names for this local name, but it doesn't 2050 // There may be several export names for this local name, but it doesn't
2037 // matter which one we pick, as they all map to the same cell. 2051 // matter which one we pick, as they all map to the same cell.
2038 auto it = mod->regular_exports().find(variable->raw_name()); 2052 auto it = mod->regular_exports().find(variable->raw_name());
2039 DCHECK(it != mod->regular_exports().end()); 2053 DCHECK(it != mod->regular_exports().end());
2040 2054
2041 RegisterList args = register_allocator()->NewRegisterList(2); 2055 RegisterList args = register_allocator()->NewRegisterList(2);
2042 builder() 2056 builder()
2043 ->StoreAccumulatorInRegister(args[1]) 2057 ->StoreAccumulatorInRegister(args[1])
2044 .LoadLiteral(it->second->export_name->string()) 2058 .LoadLiteral(it->second->export_name->string())
2045 .StoreAccumulatorInRegister(args[0]); 2059 .StoreAccumulatorInRegister(args[0]);
2046 if (needs_hole_check) { 2060 if (hole_check_mode == HoleCheckMode::kRequired) {
2047 builder()->CallRuntime(Runtime::kLoadModuleExport, args[0]); 2061 builder()->CallRuntime(Runtime::kLoadModuleExport, args[0]);
2048 BuildHoleCheckForVariableAssignment(variable, op); 2062 BuildHoleCheckForVariableAssignment(variable, op);
2049 } 2063 }
2050 builder() 2064 builder()
2051 ->CallRuntime(Runtime::kStoreModuleExport, args) 2065 ->CallRuntime(Runtime::kStoreModuleExport, args)
2052 .LoadAccumulatorWithRegister(args[1]); 2066 .LoadAccumulatorWithRegister(args[1]);
2053 break; 2067 break;
2054 } 2068 }
2055 } 2069 }
2056 } 2070 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 } 2119 }
2106 2120
2107 // Evaluate the value and potentially handle compound assignments by loading 2121 // Evaluate the value and potentially handle compound assignments by loading
2108 // the left-hand side value and performing a binary operation. 2122 // the left-hand side value and performing a binary operation.
2109 if (expr->is_compound()) { 2123 if (expr->is_compound()) {
2110 Register old_value = register_allocator()->NewRegister(); 2124 Register old_value = register_allocator()->NewRegister();
2111 switch (assign_type) { 2125 switch (assign_type) {
2112 case VARIABLE: { 2126 case VARIABLE: {
2113 VariableProxy* proxy = expr->target()->AsVariableProxy(); 2127 VariableProxy* proxy = expr->target()->AsVariableProxy();
2114 BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(), 2128 BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
2115 proxy->needs_hole_check()); 2129 proxy->hole_check_mode());
2116 builder()->StoreAccumulatorInRegister(old_value); 2130 builder()->StoreAccumulatorInRegister(old_value);
2117 break; 2131 break;
2118 } 2132 }
2119 case NAMED_PROPERTY: { 2133 case NAMED_PROPERTY: {
2120 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2134 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2121 builder() 2135 builder()
2122 ->LoadNamedProperty(object, name, feedback_index(slot)) 2136 ->LoadNamedProperty(object, name, feedback_index(slot))
2123 .StoreAccumulatorInRegister(old_value); 2137 .StoreAccumulatorInRegister(old_value);
2124 break; 2138 break;
2125 } 2139 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2158 2172
2159 // Store the value. 2173 // Store the value.
2160 builder()->SetExpressionPosition(expr); 2174 builder()->SetExpressionPosition(expr);
2161 FeedbackVectorSlot slot = expr->AssignmentSlot(); 2175 FeedbackVectorSlot slot = expr->AssignmentSlot();
2162 switch (assign_type) { 2176 switch (assign_type) {
2163 case VARIABLE: { 2177 case VARIABLE: {
2164 // TODO(oth): The BuildVariableAssignment() call is hard to reason about. 2178 // TODO(oth): The BuildVariableAssignment() call is hard to reason about.
2165 // Is the value in the accumulator safe? Yes, but scary. 2179 // Is the value in the accumulator safe? Yes, but scary.
2166 VariableProxy* proxy = expr->target()->AsVariableProxy(); 2180 VariableProxy* proxy = expr->target()->AsVariableProxy();
2167 BuildVariableAssignment(proxy->var(), expr->op(), slot, 2181 BuildVariableAssignment(proxy->var(), expr->op(), slot,
2168 proxy->needs_hole_check()); 2182 proxy->hole_check_mode());
2169 break; 2183 break;
2170 } 2184 }
2171 case NAMED_PROPERTY: 2185 case NAMED_PROPERTY:
2172 builder()->StoreNamedProperty(object, name, feedback_index(slot), 2186 builder()->StoreNamedProperty(object, name, feedback_index(slot),
2173 language_mode()); 2187 language_mode());
2174 break; 2188 break;
2175 case KEYED_PROPERTY: 2189 case KEYED_PROPERTY:
2176 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 2190 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
2177 language_mode()); 2191 language_mode());
2178 break; 2192 break;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2386 builder()->StoreAccumulatorInRegister(callee); 2400 builder()->StoreAccumulatorInRegister(callee);
2387 break; 2401 break;
2388 } 2402 }
2389 case Call::GLOBAL_CALL: { 2403 case Call::GLOBAL_CALL: {
2390 // Receiver is undefined for global calls. 2404 // Receiver is undefined for global calls.
2391 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 2405 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
2392 // Load callee as a global variable. 2406 // Load callee as a global variable.
2393 VariableProxy* proxy = callee_expr->AsVariableProxy(); 2407 VariableProxy* proxy = callee_expr->AsVariableProxy();
2394 BuildVariableLoadForAccumulatorValue(proxy->var(), 2408 BuildVariableLoadForAccumulatorValue(proxy->var(),
2395 proxy->VariableFeedbackSlot(), 2409 proxy->VariableFeedbackSlot(),
2396 proxy->needs_hole_check()); 2410 proxy->hole_check_mode());
2397 builder()->StoreAccumulatorInRegister(callee); 2411 builder()->StoreAccumulatorInRegister(callee);
2398 break; 2412 break;
2399 } 2413 }
2400 case Call::LOOKUP_SLOT_CALL: 2414 case Call::LOOKUP_SLOT_CALL:
2401 case Call::POSSIBLY_EVAL_CALL: { 2415 case Call::POSSIBLY_EVAL_CALL: {
2402 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { 2416 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) {
2403 RegisterAllocationScope inner_register_scope(this); 2417 RegisterAllocationScope inner_register_scope(this);
2404 Register name = register_allocator()->NewRegister(); 2418 Register name = register_allocator()->NewRegister();
2405 2419
2406 // Call %LoadLookupSlotForCall to get the callee and receiver. 2420 // Call %LoadLookupSlotForCall to get the callee and receiver.
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 VisitForEffect(expr->expression()); 2558 VisitForEffect(expr->expression());
2545 builder()->LoadUndefined(); 2559 builder()->LoadUndefined();
2546 } 2560 }
2547 2561
2548 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { 2562 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
2549 if (expr->expression()->IsVariableProxy()) { 2563 if (expr->expression()->IsVariableProxy()) {
2550 // Typeof does not throw a reference error on global variables, hence we 2564 // Typeof does not throw a reference error on global variables, hence we
2551 // perform a non-contextual load in case the operand is a variable proxy. 2565 // perform a non-contextual load in case the operand is a variable proxy.
2552 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2566 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2553 BuildVariableLoadForAccumulatorValue( 2567 BuildVariableLoadForAccumulatorValue(
2554 proxy->var(), proxy->VariableFeedbackSlot(), proxy->needs_hole_check(), 2568 proxy->var(), proxy->VariableFeedbackSlot(), proxy->hole_check_mode(),
2555 INSIDE_TYPEOF); 2569 INSIDE_TYPEOF);
2556 } else { 2570 } else {
2557 VisitForAccumulatorValue(expr->expression()); 2571 VisitForAccumulatorValue(expr->expression());
2558 } 2572 }
2559 builder()->TypeOf(); 2573 builder()->TypeOf();
2560 } 2574 }
2561 2575
2562 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { 2576 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
2563 if (execution_result()->IsEffect()) { 2577 if (execution_result()->IsEffect()) {
2564 VisitForEffect(expr->expression()); 2578 VisitForEffect(expr->expression());
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 2685
2672 // Evaluate LHS expression and get old value. 2686 // Evaluate LHS expression and get old value.
2673 Register object, key, old_value; 2687 Register object, key, old_value;
2674 RegisterList super_property_args; 2688 RegisterList super_property_args;
2675 Handle<String> name; 2689 Handle<String> name;
2676 switch (assign_type) { 2690 switch (assign_type) {
2677 case VARIABLE: { 2691 case VARIABLE: {
2678 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2692 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2679 BuildVariableLoadForAccumulatorValue(proxy->var(), 2693 BuildVariableLoadForAccumulatorValue(proxy->var(),
2680 proxy->VariableFeedbackSlot(), 2694 proxy->VariableFeedbackSlot(),
2681 proxy->needs_hole_check()); 2695 proxy->hole_check_mode());
2682 break; 2696 break;
2683 } 2697 }
2684 case NAMED_PROPERTY: { 2698 case NAMED_PROPERTY: {
2685 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2699 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2686 object = VisitForRegisterValue(property->obj()); 2700 object = VisitForRegisterValue(property->obj());
2687 name = property->key()->AsLiteral()->AsPropertyName(); 2701 name = property->key()->AsLiteral()->AsPropertyName();
2688 builder()->LoadNamedProperty(object, name, feedback_index(slot)); 2702 builder()->LoadNamedProperty(object, name, feedback_index(slot));
2689 break; 2703 break;
2690 } 2704 }
2691 case KEYED_PROPERTY: { 2705 case KEYED_PROPERTY: {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2736 FeedbackVectorSlot slot = expr->CountBinaryOpFeedbackSlot(); 2750 FeedbackVectorSlot slot = expr->CountBinaryOpFeedbackSlot();
2737 builder()->CountOperation(expr->binary_op(), feedback_index(slot)); 2751 builder()->CountOperation(expr->binary_op(), feedback_index(slot));
2738 2752
2739 // Store the value. 2753 // Store the value.
2740 builder()->SetExpressionPosition(expr); 2754 builder()->SetExpressionPosition(expr);
2741 FeedbackVectorSlot feedback_slot = expr->CountSlot(); 2755 FeedbackVectorSlot feedback_slot = expr->CountSlot();
2742 switch (assign_type) { 2756 switch (assign_type) {
2743 case VARIABLE: { 2757 case VARIABLE: {
2744 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2758 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2745 BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot, 2759 BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot,
2746 proxy->needs_hole_check()); 2760 proxy->hole_check_mode());
2747 break; 2761 break;
2748 } 2762 }
2749 case NAMED_PROPERTY: { 2763 case NAMED_PROPERTY: {
2750 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), 2764 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot),
2751 language_mode()); 2765 language_mode());
2752 break; 2766 break;
2753 } 2767 }
2754 case KEYED_PROPERTY: { 2768 case KEYED_PROPERTY: {
2755 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), 2769 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot),
2756 language_mode()); 2770 language_mode());
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3029 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); 3043 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
3030 3044
3031 // Allocate and initialize a new arguments object and assign to the 3045 // Allocate and initialize a new arguments object and assign to the
3032 // {arguments} variable. 3046 // {arguments} variable.
3033 CreateArgumentsType type = 3047 CreateArgumentsType type =
3034 is_strict(language_mode()) || !info()->has_simple_parameters() 3048 is_strict(language_mode()) || !info()->has_simple_parameters()
3035 ? CreateArgumentsType::kUnmappedArguments 3049 ? CreateArgumentsType::kUnmappedArguments
3036 : CreateArgumentsType::kMappedArguments; 3050 : CreateArgumentsType::kMappedArguments;
3037 builder()->CreateArguments(type); 3051 builder()->CreateArguments(type);
3038 BuildVariableAssignment(variable, Token::ASSIGN, 3052 BuildVariableAssignment(variable, Token::ASSIGN,
3039 FeedbackVectorSlot::Invalid(), false); 3053 FeedbackVectorSlot::Invalid(),
3054 HoleCheckMode::kElided);
3040 } 3055 }
3041 3056
3042 void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) { 3057 void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
3043 if (rest == nullptr) return; 3058 if (rest == nullptr) return;
3044 3059
3045 // Allocate and initialize a new rest parameter and assign to the {rest} 3060 // Allocate and initialize a new rest parameter and assign to the {rest}
3046 // variable. 3061 // variable.
3047 builder()->CreateArguments(CreateArgumentsType::kRestParameter); 3062 builder()->CreateArguments(CreateArgumentsType::kRestParameter);
3048 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); 3063 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
3049 BuildVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid(), 3064 BuildVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid(),
3050 false); 3065 HoleCheckMode::kElided);
3051 } 3066 }
3052 3067
3053 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { 3068 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
3054 if (variable == nullptr) return; 3069 if (variable == nullptr) return;
3055 3070
3056 // Store the closure we were called with in the given variable. 3071 // Store the closure we were called with in the given variable.
3057 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3072 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3058 BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(), 3073 BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
3059 false); 3074 HoleCheckMode::kElided);
3060 } 3075 }
3061 3076
3062 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { 3077 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
3063 if (variable == nullptr) return; 3078 if (variable == nullptr) return;
3064 3079
3065 // Store the new target we were called with in the given variable. 3080 // Store the new target we were called with in the given variable.
3066 builder()->LoadAccumulatorWithRegister(Register::new_target()); 3081 builder()->LoadAccumulatorWithRegister(Register::new_target());
3067 BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(), 3082 BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
3068 false); 3083 HoleCheckMode::kElided);
3069 3084
3070 // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer 3085 // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
3071 // and we need to make sure {BytecodeRegisterOptimizer} flushes its state 3086 // and we need to make sure {BytecodeRegisterOptimizer} flushes its state
3072 // before a local variable containing the <new.target> is used. Using a label 3087 // before a local variable containing the <new.target> is used. Using a label
3073 // as below flushes the entire pipeline, we should be more specific here. 3088 // as below flushes the entire pipeline, we should be more specific here.
3074 BytecodeLabel flush_state_label; 3089 BytecodeLabel flush_state_label;
3075 builder()->Bind(&flush_state_label); 3090 builder()->Bind(&flush_state_label);
3076 } 3091 }
3077 3092
3078 void BytecodeGenerator::VisitFunctionClosureForContext() { 3093 void BytecodeGenerator::VisitFunctionClosureForContext() {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 } 3204 }
3190 3205
3191 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { 3206 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3192 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 3207 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3193 : Runtime::kStoreKeyedToSuper_Sloppy; 3208 : Runtime::kStoreKeyedToSuper_Sloppy;
3194 } 3209 }
3195 3210
3196 } // namespace interpreter 3211 } // namespace interpreter
3197 } // namespace internal 3212 } // namespace internal
3198 } // namespace v8 3213 } // namespace v8
OLDNEW
« 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