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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1419003002: [Interpreter] Unify global and unallocated variable access. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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 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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 case ObjectLiteral::Property::CONSTANT: 706 case ObjectLiteral::Property::CONSTANT:
707 UNREACHABLE(); 707 UNREACHABLE();
708 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 708 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 709 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
710 // Fall through. 710 // Fall through.
711 case ObjectLiteral::Property::COMPUTED: { 711 case ObjectLiteral::Property::COMPUTED: {
712 // It is safe to use [[Put]] here because the boilerplate already 712 // It is safe to use [[Put]] here because the boilerplate already
713 // contains computed properties with an uninitialized value. 713 // contains computed properties with an uninitialized value.
714 if (literal_key->value()->IsInternalizedString()) { 714 if (literal_key->value()->IsInternalizedString()) {
715 if (property->emit_store()) { 715 if (property->emit_store()) {
716 Register name = inner_temporary_register_scope.NewRegister(); 716 size_t name_index =
717 builder() 717 builder()->GetConstantPoolEntry(literal_key->AsPropertyName());
718 ->LoadLiteral(literal_key->AsPropertyName())
719 .StoreAccumulatorInRegister(name);
720 VisitForAccumulatorValue(property->value()); 718 VisitForAccumulatorValue(property->value());
721 builder()->StoreNamedProperty(literal, name, 719 builder()->StoreNamedProperty(literal, name_index,
722 feedback_index(property->GetSlot(0)), 720 feedback_index(property->GetSlot(0)),
723 language_mode()); 721 language_mode());
724 } else { 722 } else {
725 VisitForEffect(property->value()); 723 VisitForEffect(property->value());
726 } 724 }
727 } else { 725 } else {
728 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3); 726 inner_temporary_register_scope.PrepareForConsecutiveAllocations(3);
729 Register key = 727 Register key =
730 inner_temporary_register_scope.NextConsecutiveRegister(); 728 inner_temporary_register_scope.NextConsecutiveRegister();
731 Register value = 729 Register value =
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 execution_result()->SetResultInRegister(source); 928 execution_result()->SetResultInRegister(source);
931 break; 929 break;
932 } 930 }
933 case VariableLocation::PARAMETER: { 931 case VariableLocation::PARAMETER: {
934 // The parameter indices are shifted by 1 (receiver is variable 932 // The parameter indices are shifted by 1 (receiver is variable
935 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 933 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
936 Register source = builder()->Parameter(variable->index() + 1); 934 Register source = builder()->Parameter(variable->index() + 1);
937 execution_result()->SetResultInRegister(source); 935 execution_result()->SetResultInRegister(source);
938 break; 936 break;
939 } 937 }
940 case VariableLocation::GLOBAL: { 938 case VariableLocation::GLOBAL:
941 // Global var, const, or let variable. 939 case VariableLocation::UNALLOCATED: {
942 // TODO(rmcilroy): If context chain depth is short enough, do this using 940 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
943 // a generic version of LoadGlobalViaContextStub rather than calling the 941 builder()->LoadGlobal(name_index, feedback_index(slot), language_mode());
944 // runtime.
945 DCHECK(variable->IsStaticGlobalObjectProperty());
946 builder()->LoadGlobal(variable->index());
947 execution_result()->SetResultInAccumulator(); 942 execution_result()->SetResultInAccumulator();
948 break; 943 break;
949 } 944 }
950 case VariableLocation::UNALLOCATED: {
951 TemporaryRegisterScope temporary_register_scope(builder());
952 Register obj = temporary_register_scope.NewRegister();
953 builder()->LoadContextSlot(execution_context()->reg(),
954 Context::GLOBAL_OBJECT_INDEX);
955 builder()->StoreAccumulatorInRegister(obj);
956 builder()->LoadLiteral(variable->name());
957 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode());
958 execution_result()->SetResultInAccumulator();
959 break;
960 }
961 case VariableLocation::CONTEXT: { 945 case VariableLocation::CONTEXT: {
962 ContextScope* context = execution_context()->Previous(variable->scope()); 946 ContextScope* context = execution_context()->Previous(variable->scope());
963 if (context) { 947 if (context) {
964 builder()->LoadContextSlot(context->reg(), variable->index()); 948 builder()->LoadContextSlot(context->reg(), variable->index());
965 execution_result()->SetResultInAccumulator(); 949 execution_result()->SetResultInAccumulator();
966 } else { 950 } else {
967 UNIMPLEMENTED(); 951 UNIMPLEMENTED();
968 } 952 }
969 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and 953 // TODO(rmcilroy): Perform check for uninitialized legacy const, const and
970 // let variables. 954 // let variables.
(...skipping 16 matching lines...) Expand all
987 break; 971 break;
988 } 972 }
989 case VariableLocation::PARAMETER: { 973 case VariableLocation::PARAMETER: {
990 // The parameter indices are shifted by 1 (receiver is variable 974 // The parameter indices are shifted by 1 (receiver is variable
991 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 975 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
992 Register destination(builder()->Parameter(variable->index() + 1)); 976 Register destination(builder()->Parameter(variable->index() + 1));
993 builder()->StoreAccumulatorInRegister(destination); 977 builder()->StoreAccumulatorInRegister(destination);
994 RecordStoreToRegister(destination); 978 RecordStoreToRegister(destination);
995 break; 979 break;
996 } 980 }
997 case VariableLocation::GLOBAL: { 981 case VariableLocation::GLOBAL:
998 // Global var, const, or let variable.
999 // TODO(rmcilroy): If context chain depth is short enough, do this using
1000 // a generic version of LoadGlobalViaContextStub rather than calling the
1001 // runtime.
1002 DCHECK(variable->IsStaticGlobalObjectProperty());
1003 builder()->StoreGlobal(variable->index(), language_mode());
1004 break;
1005 }
1006 case VariableLocation::UNALLOCATED: { 982 case VariableLocation::UNALLOCATED: {
1007 Register value = execution_result()->NewRegister(); 983 size_t name_index = builder()->GetConstantPoolEntry(variable->name());
1008 Register obj = execution_result()->NewRegister(); 984 builder()->StoreGlobal(name_index, feedback_index(slot), language_mode());
1009 Register name = execution_result()->NewRegister();
1010
1011 // TODO(rmcilroy): Investigate whether we can avoid having to stash the
1012 // value in a register.
1013 builder()->StoreAccumulatorInRegister(value);
1014 builder()->LoadContextSlot(execution_context()->reg(),
1015 Context::GLOBAL_OBJECT_INDEX);
1016 builder()->StoreAccumulatorInRegister(obj);
1017 builder()->LoadLiteral(variable->name());
1018 builder()->StoreAccumulatorInRegister(name);
1019 builder()->LoadAccumulatorWithRegister(value);
1020 builder()->StoreNamedProperty(obj, name, feedback_index(slot),
1021 language_mode());
1022 break; 985 break;
1023 } 986 }
1024 case VariableLocation::CONTEXT: { 987 case VariableLocation::CONTEXT: {
1025 // TODO(rmcilroy): support const mode initialization. 988 // TODO(rmcilroy): support const mode initialization.
1026 ContextScope* context = execution_context()->Previous(variable->scope()); 989 ContextScope* context = execution_context()->Previous(variable->scope());
1027 if (context) { 990 if (context) {
1028 builder()->StoreContextSlot(context->reg(), variable->index()); 991 builder()->StoreContextSlot(context->reg(), variable->index());
1029 } else { 992 } else {
1030 UNIMPLEMENTED(); 993 UNIMPLEMENTED();
1031 } 994 }
1032 break; 995 break;
1033 } 996 }
1034 case VariableLocation::LOOKUP: 997 case VariableLocation::LOOKUP:
1035 UNIMPLEMENTED(); 998 UNIMPLEMENTED();
1036 } 999 }
1037 } 1000 }
1038 1001
1039 1002
1040 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 1003 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
1041 DCHECK(expr->target()->IsValidReferenceExpression()); 1004 DCHECK(expr->target()->IsValidReferenceExpression());
1042 Register object, key; 1005 Register object, key;
1006 size_t name_index;
1043 1007
1044 // Left-hand side can only be a property, a global or a variable slot. 1008 // Left-hand side can only be a property, a global or a variable slot.
1045 Property* property = expr->target()->AsProperty(); 1009 Property* property = expr->target()->AsProperty();
1046 LhsKind assign_type = Property::GetAssignType(property); 1010 LhsKind assign_type = Property::GetAssignType(property);
1047 1011
1048 // Evaluate LHS expression. 1012 // Evaluate LHS expression.
1049 switch (assign_type) { 1013 switch (assign_type) {
1050 case VARIABLE: 1014 case VARIABLE:
1051 // Nothing to do to evaluate variable assignment LHS. 1015 // Nothing to do to evaluate variable assignment LHS.
1052 break; 1016 break;
1053 case NAMED_PROPERTY: { 1017 case NAMED_PROPERTY: {
1054 object = VisitForRegisterValue(property->obj()); 1018 object = VisitForRegisterValue(property->obj());
1055 key = execution_result()->NewRegister(); 1019 name_index = builder()->GetConstantPoolEntry(
1056 builder()->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()); 1020 property->key()->AsLiteral()->AsPropertyName());
1057 builder()->StoreAccumulatorInRegister(key);
1058 break; 1021 break;
1059 } 1022 }
1060 case KEYED_PROPERTY: { 1023 case KEYED_PROPERTY: {
1061 object = VisitForRegisterValue(property->obj()); 1024 object = VisitForRegisterValue(property->obj());
1062 key = VisitForRegisterValue(property->key()); 1025 key = VisitForRegisterValue(property->key());
1063 break; 1026 break;
1064 } 1027 }
1065 case NAMED_SUPER_PROPERTY: 1028 case NAMED_SUPER_PROPERTY:
1066 case KEYED_SUPER_PROPERTY: 1029 case KEYED_SUPER_PROPERTY:
1067 UNIMPLEMENTED(); 1030 UNIMPLEMENTED();
(...skipping 11 matching lines...) Expand all
1079 FeedbackVectorSlot slot = expr->AssignmentSlot(); 1042 FeedbackVectorSlot slot = expr->AssignmentSlot();
1080 switch (assign_type) { 1043 switch (assign_type) {
1081 case VARIABLE: { 1044 case VARIABLE: {
1082 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. 1045 // TODO(oth): The VisitVariableAssignment() call is hard to reason about.
1083 // Is the value in the accumulator safe? Yes, but scary. 1046 // Is the value in the accumulator safe? Yes, but scary.
1084 Variable* variable = expr->target()->AsVariableProxy()->var(); 1047 Variable* variable = expr->target()->AsVariableProxy()->var();
1085 VisitVariableAssignment(variable, slot); 1048 VisitVariableAssignment(variable, slot);
1086 break; 1049 break;
1087 } 1050 }
1088 case NAMED_PROPERTY: 1051 case NAMED_PROPERTY:
1089 builder()->StoreNamedProperty(object, key, feedback_index(slot), 1052 builder()->StoreNamedProperty(object, name_index, feedback_index(slot),
1090 language_mode()); 1053 language_mode());
1091 break; 1054 break;
1092 case KEYED_PROPERTY: 1055 case KEYED_PROPERTY:
1093 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 1056 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
1094 language_mode()); 1057 language_mode());
1095 break; 1058 break;
1096 case NAMED_SUPER_PROPERTY: 1059 case NAMED_SUPER_PROPERTY:
1097 case KEYED_SUPER_PROPERTY: 1060 case KEYED_SUPER_PROPERTY:
1098 UNIMPLEMENTED(); 1061 UNIMPLEMENTED();
1099 } 1062 }
(...skipping 10 matching lines...) Expand all
1110 } 1073 }
1111 1074
1112 1075
1113 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 1076 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
1114 LhsKind property_kind = Property::GetAssignType(expr); 1077 LhsKind property_kind = Property::GetAssignType(expr);
1115 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); 1078 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
1116 switch (property_kind) { 1079 switch (property_kind) {
1117 case VARIABLE: 1080 case VARIABLE:
1118 UNREACHABLE(); 1081 UNREACHABLE();
1119 case NAMED_PROPERTY: { 1082 case NAMED_PROPERTY: {
1120 builder()->LoadLiteral(expr->key()->AsLiteral()->AsPropertyName()); 1083 size_t name_index = builder()->GetConstantPoolEntry(
1121 builder()->LoadNamedProperty(obj, feedback_index(slot), language_mode()); 1084 expr->key()->AsLiteral()->AsPropertyName());
1085 builder()->LoadNamedProperty(obj, name_index, feedback_index(slot),
1086 language_mode());
1122 break; 1087 break;
1123 } 1088 }
1124 case KEYED_PROPERTY: { 1089 case KEYED_PROPERTY: {
1125 VisitForAccumulatorValue(expr->key()); 1090 VisitForAccumulatorValue(expr->key());
1126 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); 1091 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode());
1127 break; 1092 break;
1128 } 1093 }
1129 case NAMED_SUPER_PROPERTY: 1094 case NAMED_SUPER_PROPERTY:
1130 case KEYED_SUPER_PROPERTY: 1095 case KEYED_SUPER_PROPERTY:
1131 UNIMPLEMENTED(); 1096 UNIMPLEMENTED();
1132 } 1097 }
1133 execution_result()->SetResultInAccumulator();
1134 } 1098 }
1135 1099
1136 1100
1137 void BytecodeGenerator::VisitProperty(Property* expr) { 1101 void BytecodeGenerator::VisitProperty(Property* expr) {
1138 Register obj = VisitForRegisterValue(expr->obj()); 1102 Register obj = VisitForRegisterValue(expr->obj());
1139 VisitPropertyLoad(obj, expr); 1103 VisitPropertyLoad(obj, expr);
1104 execution_result()->SetResultInAccumulator();
1140 } 1105 }
1141 1106
1142 1107
1143 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { 1108 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
1144 // Visit arguments and place in a contiguous block of temporary 1109 // Visit arguments and place in a contiguous block of temporary
1145 // registers. Return the first temporary register corresponding to 1110 // registers. Return the first temporary register corresponding to
1146 // the first argument. 1111 // the first argument.
1147 // 1112 //
1148 // NB the caller may have already called 1113 // NB the caller may have already called
1149 // PrepareForConsecutiveAllocations() with args->length() + N. The 1114 // PrepareForConsecutiveAllocations() with args->length() + N. The
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 ZoneList<Expression*>* args = expr->arguments(); 1148 ZoneList<Expression*>* args = expr->arguments();
1184 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1); 1149 execution_result()->PrepareForConsecutiveAllocations(args->length() + 1);
1185 Register receiver = execution_result()->NextConsecutiveRegister(); 1150 Register receiver = execution_result()->NextConsecutiveRegister();
1186 1151
1187 switch (call_type) { 1152 switch (call_type) {
1188 case Call::PROPERTY_CALL: { 1153 case Call::PROPERTY_CALL: {
1189 Property* property = callee_expr->AsProperty(); 1154 Property* property = callee_expr->AsProperty();
1190 if (property->IsSuperAccess()) { 1155 if (property->IsSuperAccess()) {
1191 UNIMPLEMENTED(); 1156 UNIMPLEMENTED();
1192 } 1157 }
1158
1193 VisitForAccumulatorValue(property->obj()); 1159 VisitForAccumulatorValue(property->obj());
1194 builder()->StoreAccumulatorInRegister(receiver); 1160 builder()->StoreAccumulatorInRegister(receiver);
1195 // Need a result scope here to keep our consecutive
1196 // temporaries.
1197 AccumulatorResultScope accumulator_execution_result(this);
oth 2015/10/22 10:54:30 A comment here to say VisitProperyLoad here will n
rmcilroy 2015/10/22 13:27:48 N/A now.
1198 // Perform a property load of the callee.
1199 VisitPropertyLoad(receiver, property); 1161 VisitPropertyLoad(receiver, property);
1200 builder()->StoreAccumulatorInRegister(callee); 1162 builder()->StoreAccumulatorInRegister(callee);
1201 break; 1163 break;
1202 } 1164 }
1203 case Call::GLOBAL_CALL: { 1165 case Call::GLOBAL_CALL: {
1204 // Receiver is undefined for global calls. 1166 // Receiver is undefined for global calls.
1205 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 1167 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
1206 // Load callee as a global variable. 1168 // Load callee as a global variable.
1207 VariableProxy* proxy = callee_expr->AsVariableProxy(); 1169 VariableProxy* proxy = callee_expr->AsVariableProxy();
1208 // Result scope for VisitVariableLoad to avoid using our temporaries 1170 // Result scope for VisitVariableLoad to avoid using our temporaries
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 } 1488 }
1527 } 1489 }
1528 1490
1529 1491
1530 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 1492 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
1531 ObjectLiteralProperty* property, 1493 ObjectLiteralProperty* property,
1532 int slot_number) { 1494 int slot_number) {
1533 Expression* expr = property->value(); 1495 Expression* expr = property->value();
1534 if (!FunctionLiteral::NeedsHomeObject(expr)) return; 1496 if (!FunctionLiteral::NeedsHomeObject(expr)) return;
1535 1497
1536 // TODO(rmcilroy): Remove UNIMPLEMENTED once we have tests for setting the
1537 // home object.
1538 UNIMPLEMENTED(); 1498 UNIMPLEMENTED();
1539
1540 TemporaryRegisterScope temporary_register_scope(builder());
1541 Register name = temporary_register_scope.NewRegister();
1542 isolate()->factory()->home_object_symbol();
1543 builder()
1544 ->LoadLiteral(isolate()->factory()->home_object_symbol())
1545 .StoreAccumulatorInRegister(name)
1546 .StoreNamedProperty(home_object, name,
1547 feedback_index(property->GetSlot(slot_number)),
1548 language_mode());
1549 } 1499 }
1550 1500
1551 1501
1552 void BytecodeGenerator::VisitFunctionClosureForContext() { 1502 void BytecodeGenerator::VisitFunctionClosureForContext() {
1553 Scope* closure_scope = execution_context()->scope()->ClosureScope(); 1503 Scope* closure_scope = execution_context()->scope()->ClosureScope();
1554 if (closure_scope->is_script_scope() || 1504 if (closure_scope->is_script_scope() ||
1555 closure_scope->is_module_scope()) { 1505 closure_scope->is_module_scope()) {
1556 // Contexts nested in the native context have a canonical empty function as 1506 // Contexts nested in the native context have a canonical empty function as
1557 // their closure, not the anonymous closure containing the global code. 1507 // their closure, not the anonymous closure containing the global code.
1558 // Pass a SMI sentinel and let the runtime look up the empty function. 1508 // Pass a SMI sentinel and let the runtime look up the empty function.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 } 1601 }
1652 1602
1653 1603
1654 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1604 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1655 return info()->feedback_vector()->GetIndex(slot); 1605 return info()->feedback_vector()->GetIndex(slot);
1656 } 1606 }
1657 1607
1658 } // namespace interpreter 1608 } // namespace interpreter
1659 } // namespace internal 1609 } // namespace internal
1660 } // namespace v8 1610 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698